From python at mrabarnett.plus.com Mon May 1 12:59:51 2023 From: python at mrabarnett.plus.com (MRAB) Date: Mon, 1 May 2023 17:59:51 +0100 Subject: Using loguru in a library In-Reply-To: References: Message-ID: <349b36c4-2de3-f537-4c90-a738243d925d@mrabarnett.plus.com> On 2023-04-30 16:40, Roy Hann wrote: > Is there anyone using loguru (loguru 0.5.3 in my case) successfully in a > library? > > > In my __init__.py in mylib I do > > logger.disable('mylib') > > which definitely works. I don't get any more logging. > > I "pip install ." the library, then in mytest.py I do > > import mylib > logger.enable('mylib') > > expecting that it would report any log messages above level DEBUG, just > as it does when I don't disable logging. Unfortunately it doesn't > have any effect; it doesn't report any logging from mylib. > > I have verified that __name__ is visible in the library and is 'mylib'. > > I would also have expected that logger.enable(None) would turn all the > logging on everywhere but it seems not. > > I have probably misunderstood how logger.enable() is supposed to be > used. Can anyone share a brief example? > According to the docs, the argument is the name of the module. In your example, the name of the module (i.e. file) is "__init__"; "mylib" is the name of the package. From specially at processed.almost.meat Tue May 2 04:17:30 2023 From: specially at processed.almost.meat (Roy Hann) Date: Tue, 2 May 2023 08:17:30 -0000 (UTC) Subject: Using loguru in a library References: <349b36c4-2de3-f537-4c90-a738243d925d@mrabarnett.plus.com> Message-ID: MRAB wrote: > On 2023-04-30 16:40, Roy Hann wrote: >> Is there anyone using loguru (loguru 0.5.3 in my case) successfully in a >> library? >> >> >> In my __init__.py in mylib I do >> >> logger.disable('mylib') >> >> which definitely works. I don't get any more logging. >> >> I "pip install ." the library, then in mytest.py I do >> >> import mylib >> logger.enable('mylib') >> >> expecting that it would report any log messages above level DEBUG, just >> as it does when I don't disable logging. Unfortunately it doesn't >> have any effect; it doesn't report any logging from mylib. >> >> I have verified that __name__ is visible in the library and is 'mylib'. >> >> I would also have expected that logger.enable(None) would turn all the >> logging on everywhere but it seems not. >> >> I have probably misunderstood how logger.enable() is supposed to be >> used. Can anyone share a brief example? >> > According to the docs, the argument is the name of the module. > > In your example, the name of the module (i.e. file) is "__init__"; > "mylib" is the name of the package. Thanks for taking a look at this. I will continue to play around with it using your suggestion, but according to the snippets and recipes for loguru at https://loguru.readthedocs.io/en/stable/resources/recipes.html#configuring-loguru-to-be-used-by-a-library-or-an-application I need to refer to the package name in disable() in __init__.py, not the module/file name, and so I expect to use it in enable() in my main. Also, as mentioned, I have already verified that __name__ in my package is referring to the package name not the module. Since every package will have a __init__.py even if it's empty, using the module name to control logging by package would be difficult. Or so I say. My code isn't working so I am wrong about some or all of this. I'll keep tinkering and looking out for advice/suggestions here. Roy From aapost at idontexist.club Tue May 2 11:19:37 2023 From: aapost at idontexist.club (aapost) Date: Tue, 2 May 2023 11:19:37 -0400 Subject: Note when migrating '#' formats for PyArgs_ParseTuple Message-ID: Just in case anyone else runs in to it. If you have code such as: char* a; char* b; char* d; int size; if (!PyArg_ParseTuple(args, "sss#:f", &a, &b, &d, &size)) return NULL; and it tells you to: #define PY_SSIZE_T_CLEAN #include "Python.h" Be sure to change int size; to: Py_ssize_t size; If you forget, your code will compile fine and still work perfectly fine on all py2 and py3 i386 variants, but will break 64bit variants in very non-obvious ways. In the above example the mismatched pointer type of size messes up the seemingly unrelated pointer a padr a 0x7f1f00000000 padr b 0x7f1fa656b960 padr d 0x7f1fa65579a0 So while accessing the s# argument works fine, you get a segfault when you access a I spent quite a while chasing my tail researching variadics, picking apart the code trying to understand how and where 'a' gets stomped on before I realized the size type mismatch. -- On that note, I will say that the removal of distutils/setup.py-ability from 3.12 without a similarly simple out of the box replacement is unfortunate. (if setup.py usage had design flaws that lead to deprecation fine, but python should have some form of stand alone equivalency included out of the box by default) For researching issues like the above, and for people who want to use python for off-internet projects, it is nice to be able to spin up a virtual machine from any said era, and do a ./configure make ./python setup.py install --user As things diverge in the future, things start to break, and you don't always have all the pieces to put it back together, and pip kind of sucks and is not simple when it doesn't work. It's pushy, it wants to force everyone to connect to the hive, it demands ssl, etc, when I just want it to shut up and make ./python -m pip install . do what ./python setup.py install --user does I will figure out what works best situationally moving forward as far as work arounds (probably modifying pip), but just saying, the modern way of jenkinizing everything sucks, and takes the fun out of tinkering in a cave. From dieter at handshake.de Tue May 2 12:26:16 2023 From: dieter at handshake.de (Dieter Maurer) Date: Tue, 2 May 2023 18:26:16 +0200 Subject: Using loguru in a library In-Reply-To: References: Message-ID: <25681.14760.335750.148299@ixdm.fritz.box> Roy Hann wrote at 2023-4-30 15:40 -0000: >Is there anyone using loguru (loguru 0.5.3 in my case) successfully in a >library? > ... > import mylib > logger.enable('mylib') > >expecting that it would report any log messages above level DEBUG, just >as it does when I don't disable logging. Have you configured the logging system? Note that `logging.config.fileConfig` may do strange things regarding disabling (due to its default parameter `disable_existing_loggers=True`). I had several cases of missing log entries because `fileConfig` had disabled already existing loggers. From kevinmwilson1956 at yahoo.com Tue May 2 16:39:35 2023 From: kevinmwilson1956 at yahoo.com (Kevin M. Wilson) Date: Tue, 2 May 2023 20:39:35 +0000 (UTC) Subject: Editing PEP-8, in particular "expected 2 blanks, found 1 References: <1432055058.3122695.1683059975763.ref@mail.yahoo.com> Message-ID: <1432055058.3122695.1683059975763@mail.yahoo.com> Folks, help please! What the @#$! are these doing popping up. Code styles are personal, and not subject to debate.Where can I edit these out of my IDE? Kevin "When you pass through the waters, I will be with you: and when you?pass through the rivers, they will not sweep over?you. When?you walk?through the fire, you will not be burned: the flames will not set you ablaze."? ? ? Isaiah 43:2 | | Virus-free.www.avg.com | From 2QdxY4RzWzUUiLuE at potatochowder.com Tue May 2 17:32:26 2023 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Tue, 2 May 2023 17:32:26 -0400 Subject: Editing PEP-8, in particular "expected 2 blanks, found 1 In-Reply-To: <1432055058.3122695.1683059975763@mail.yahoo.com> References: <1432055058.3122695.1683059975763.ref@mail.yahoo.com> <1432055058.3122695.1683059975763@mail.yahoo.com> Message-ID: On 2023-05-02 at 20:39:35 +0000, "Kevin M. Wilson via Python-list" wrote: > [...] Where can I edit these out of my IDE? I doubt anyone will know unless you at least tell us which IDE you're using. From list1 at tompassin.net Tue May 2 18:08:40 2023 From: list1 at tompassin.net (Thomas Passin) Date: Tue, 2 May 2023 18:08:40 -0400 Subject: Editing PEP-8, in particular "expected 2 blanks, found 1 In-Reply-To: <1432055058.3122695.1683059975763@mail.yahoo.com> References: <1432055058.3122695.1683059975763.ref@mail.yahoo.com> <1432055058.3122695.1683059975763@mail.yahoo.com> Message-ID: On 5/2/2023 4:39 PM, Kevin M. Wilson via Python-list wrote: > Folks, help please! What the @#$! are these doing popping up. Code styles are personal, and not subject to debate.Where can I edit these out of my IDE? > Kevin > "When you pass through the waters, I will be with you: and when you?pass through the rivers, they will not sweep over?you. When?you walk?through the fire, you will not be burned: the flames will not set you ablaze." > Isaiah 43:2 > > | | Virus-free.www.avg.com | > It might help if you gave a hint about what IDE is involved... From specially at processed.almost.meat Tue May 2 18:10:11 2023 From: specially at processed.almost.meat (Roy Hann) Date: Tue, 2 May 2023 22:10:11 -0000 (UTC) Subject: Using loguru in a library References: <25681.14760.335750.148299@ixdm.fritz.box> Message-ID: Dieter Maurer wrote: > Roy Hann wrote at 2023-4-30 15:40 -0000: >>Is there anyone using loguru (loguru 0.5.3 in my case) successfully in a >>library? >> ... >> import mylib >> logger.enable('mylib') >> >>expecting that it would report any log messages above level DEBUG, just >>as it does when I don't disable logging. > > Have you configured the logging system? > > Note that `logging.config.fileConfig` may do strange things > regarding disabling (due to its default parameter > `disable_existing_loggers=True`). > I had several cases of missing log entries because `fileConfig` > had disabled already existing loggers. Thank you for the response Dieter. I am using the loguru package, not the logging package. I think my next step is going to have be creating a minimal test case to post on stackoverflow. :-P Roy From artie.ziff at gmail.com Wed May 3 06:41:26 2023 From: artie.ziff at gmail.com (Artie Ziff) Date: Wed, 3 May 2023 03:41:26 -0700 Subject: double bracket integer index in pandas; Is this a legal syntax Message-ID: Hello, I am hope that pandas questions are OK here. In a panda lecture, I did not get the expected result. I tried this on two different platforms (old macOS distro and up-to-date Ubuntu Linux distro, 22.04) The Linux distro has: python 3.10.11 pandas 1.5.2 conda 23.3.1 Is this double bracket form, df[[1]], deprecated... maybe? There is data in a dataframe, df. >>> subset = df[[1]] Traceback (most recent call last): File "", line 1, in File "/home/dks/anaconda3/lib/python3.10/site-packages/pandas/core/frame.py", line 3811, in __getitem__ indexer = self.columns._get_indexer_strict(key, "columns")[1] File "/home/dks/anaconda3/lib/python3.10/site-packages/pandas/core/indexes/base.py", line 6113, in _get_indexer_strict self._raise_if_missing(keyarr, indexer, axis_name) File "/home/dks/anaconda3/lib/python3.10/site-packages/pandas/core/indexes/base.py", line 6173, in _raise_if_missing raise KeyError(f"None of [{key}] are in the [{axis_name}]") KeyError: "None of [Int64Index([1], dtype='int64')] are in the [columns]" What could be making this fail? Thank you! az From cs at cskk.id.au Wed May 3 07:37:24 2023 From: cs at cskk.id.au (Cameron Simpson) Date: Wed, 3 May 2023 21:37:24 +1000 Subject: double bracket integer index in pandas; Is this a legal syntax In-Reply-To: References: Message-ID: On 03May2023 03:41, Artie Ziff wrote: >I am hope that pandas questions are OK here. There are some pandas users here. >In a panda lecture, I did not get the expected result. >I tried this on two different platforms >(old macOS distro and up-to-date Ubuntu Linux distro, 22.04) > >The Linux distro has: >python 3.10.11 >pandas 1.5.2 >conda 23.3.1 > >Is this double bracket form, df[[1]], deprecated... maybe? > >There is data in a dataframe, df. > >>>> subset = df[[1]] Whether this works depends on the contents of the dataframe. You're supplying this index: [1] which is a list of ints (with just one int). Have a look at this page: https://pandas.pydata.org/docs/user_guide/indexing.html If you suppply a list, it expects a list of labels. Is 1 a valid label for your particular dataframe? Cheers, Cameron Simpson From fedor.tryfanau at gmail.com Wed May 3 05:45:36 2023 From: fedor.tryfanau at gmail.com (fedor tryfanau) Date: Wed, 3 May 2023 12:45:36 +0300 Subject: An "adapter", superset of an iterator Message-ID: I've been using python as a tool to solve competitive programming problems for a while now and I've noticed a feature, python would benefit from having. Consider "reversed(enumerate(a))". This is a perfectly readable code, except it's wrong in the current version of python. That's because enumerate returns an iterator, but reversed can take only a sequence type. The feature I am describing (and proposing) solves this. Introducing an adapter type: this is an iterator, but it's items can be accessed out of order. More formally it has to: 1. Have __getitem__ to allow access by index 2. Have __len__ 3. Be immutable (It is a lot like the sequence protocol) An adapter can be converted to an iterator by accessing it from 0 to len(adapter). Which is done by iter(). (or by __iter__, I don't know which implementation would be "right") ``` iter(a) #is equivalent to (a[i] for i in range(len(a))) ``` For example any tuple is a valid adapter and any list can be easily converted to one. Built-in adapter-generators: "map" function should really return an adapter. ``` #possible implementation m=map(lambda x:x+1,[1,2,3,4,5]) #lambda is not called print(m[3])# gives 5 by calling the lambda on list's 3rd element, which is 4 #simplified implementation class map: def __init__(self,f,a): self.f=f self.a=a def __getitem__(self,idx): return self.f(self.a[idx]) def __len__(self): return len(self.a) ``` enumerate should really return an adapter ``` #simplified implementation class enumerate: def __init__(self,a): self.a = a def __getitem__(self,idx): return idx,self.a[idx] def __len__(self): return len(self.a) ``` reversed should really return an adapter ``` #simplified implementation class reversed: def __init__(self,a): self.a = a self.length=len(a) def __getitem__(self,idx): return self.a[self.length-idx-1] def __len__(self): return self.length ``` zip should really return an adapter range should really return an adapter filter should *not* return an adapter All of those functions return an adapter and take in an adapter. But some (excluding "reversed") should be able take an iterator and return an iterator. So the way I imagine a possible release version to work is that "reversed(enumerate(a))" works if a is an adapter and throws an exception if not Perhaps there should be even an adapter comprehension: ``` Add1 = (a+1 for a) #is equivalent to Add1 = lambda s: map((lambda a: a+1),s) transformed = Add1([1,2,3]) print(transformed[1])# should be 3 ``` This adapter feature also allows you to not use a key argument "key=" for certain functions (which could be non-existing). For example bisect.bisect functions before 3.10 didn't have a key= argument. Some third-party libraries could do this with it's functions too. (Subject to change) From specially at processed.almost.meat Wed May 3 06:02:45 2023 From: specially at processed.almost.meat (Roy Hann) Date: Wed, 3 May 2023 10:02:45 -0000 (UTC) Subject: Editing PEP-8, in particular "expected 2 blanks, found 1 References: <1432055058.3122695.1683059975763.ref@mail.yahoo.com> <1432055058.3122695.1683059975763@mail.yahoo.com> Message-ID: Kevin M. Wilson wrote: > Folks, help please! What the @#$! are these doing popping up. Code styles are personal, and not subject to debate. [snip] "Expected 2 blanks"? Or "Expected 2 blank _lines_"? Two blank lines between function/method definitions has been recommended for more than 20 years. When I first started using Python I found a lot of the PEP-8 style recommendations whimsical and annoying. But I've come to appreciate most of them and no longer feel a strong urge to go my own way. I even use black now. There are plenty of seriously bad habits in our industry. I save my individualism for fighting things that are demonstraby harmful. Roy From list1 at tompassin.net Wed May 3 13:30:50 2023 From: list1 at tompassin.net (Thomas Passin) Date: Wed, 3 May 2023 13:30:50 -0400 Subject: An "adapter", superset of an iterator In-Reply-To: References: Message-ID: <536dd246-8029-47dd-1924-859b540b21cc@tompassin.net> On 5/3/2023 5:45 AM, fedor tryfanau wrote: > I've been using python as a tool to solve competitive programming problems > for a while now and I've noticed a feature, python would benefit from > having. > Consider "reversed(enumerate(a))". This is a perfectly readable code, > except it's wrong in the current version of python. That's because > enumerate returns an iterator, but reversed can take only a sequence type. Depending on what you want to give and receive, enumerate(reversed(a)) will do the job here. Otherwise list() or tuple() can achieve some of the same things. > The feature I am describing (and proposing) solves this. > Introducing an adapter type: this is an iterator, but it's items can be > accessed out of order. > More formally it has to: > 1. Have __getitem__ to allow access by index > 2. Have __len__ > 3. Be immutable > (It is a lot like the sequence protocol) > > An adapter can be converted to an iterator by accessing it from 0 to > len(adapter). Which is done by iter(). (or by __iter__, I don't know which > implementation would be "right") > ``` > iter(a) > #is equivalent to > (a[i] for i in range(len(a))) > ``` > For example any tuple is a valid adapter and any list can be easily > converted to one. > > Built-in adapter-generators: > "map" function should really return an adapter. > ``` > #possible implementation > m=map(lambda x:x+1,[1,2,3,4,5]) > #lambda is not called > print(m[3])# gives 5 by calling the lambda on list's 3rd element, which is 4 > #simplified implementation > class map: > def __init__(self,f,a): > self.f=f > self.a=a > def __getitem__(self,idx): > return self.f(self.a[idx]) > def __len__(self): > return len(self.a) > ``` > enumerate should really return an adapter > ``` > #simplified implementation > class enumerate: > def __init__(self,a): > self.a = a > def __getitem__(self,idx): > return idx,self.a[idx] > def __len__(self): > return len(self.a) > ``` > reversed should really return an adapter > ``` > #simplified implementation > class reversed: > def __init__(self,a): > self.a = a > self.length=len(a) > def __getitem__(self,idx): > return self.a[self.length-idx-1] > def __len__(self): > return self.length > ``` > zip should really return an adapter > range should really return an adapter > filter should *not* return an adapter > > All of those functions return an adapter and take in an adapter. But some > (excluding "reversed") should be able take an iterator and return an > iterator. > So the way I imagine a possible release version to work is that > "reversed(enumerate(a))" works if a is an adapter and throws an exception > if not > > Perhaps there should be even an adapter comprehension: > ``` > Add1 = (a+1 for a) > #is equivalent to > Add1 = lambda s: map((lambda a: a+1),s) > transformed = Add1([1,2,3]) > print(transformed[1])# should be 3 > ``` > > This adapter feature also allows you to not use a key argument "key=" for > certain functions (which could be non-existing). For example bisect.bisect > functions before 3.10 didn't have a key= argument. Some third-party > libraries could do this with it's functions too. > > (Subject to change) From oscar.j.benjamin at gmail.com Wed May 3 15:46:59 2023 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Wed, 3 May 2023 20:46:59 +0100 Subject: An "adapter", superset of an iterator In-Reply-To: <536dd246-8029-47dd-1924-859b540b21cc@tompassin.net> References: <536dd246-8029-47dd-1924-859b540b21cc@tompassin.net> Message-ID: On Wed, 3 May 2023 at 18:52, Thomas Passin wrote: > > On 5/3/2023 5:45 AM, fedor tryfanau wrote: > > I've been using python as a tool to solve competitive programming problems > > for a while now and I've noticed a feature, python would benefit from > > having. > > Consider "reversed(enumerate(a))". This is a perfectly readable code, > > except it's wrong in the current version of python. That's because > > enumerate returns an iterator, but reversed can take only a sequence type. > > Depending on what you want to give and receive, enumerate(reversed(a)) > will do the job here. Otherwise list() or tuple() can achieve some of > the same things. I don't think that is equivalent to the intended behaviour: reversed(enumerate(a)) # zip(reversed(range(len(a))), reversed(a)) enumerate(reversed(a)) # zip(range(len(a)), reversed(a)) In principle for a sequence input enumerate(a) could be something that behaves like a sequence and therefore could be reiterated or reversed etc. The enumerate(a).__reversed__ method could then delegate to a.__reversed__ and a.__len__ if they exist. This could be confusing though because the possible behaviour of enumerate(a) would be different depending on the type of a. -- Oscar From rosuav at gmail.com Wed May 3 17:29:14 2023 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 4 May 2023 07:29:14 +1000 Subject: An "adapter", superset of an iterator In-Reply-To: References: Message-ID: On Thu, 4 May 2023 at 02:25, fedor tryfanau wrote: > > I've been using python as a tool to solve competitive programming problems > for a while now and I've noticed a feature, python would benefit from > having. > Consider "reversed(enumerate(a))". This is a perfectly readable code, > except it's wrong in the current version of python. That's because > enumerate returns an iterator, but reversed can take only a sequence type. > > The feature I am describing (and proposing) solves this. > Introducing an adapter type: this is an iterator, but it's items can be > accessed out of order. > More formally it has to: > 1. Have __getitem__ to allow access by index > 2. Have __len__ > 3. Be immutable > (It is a lot like the sequence protocol) > > An adapter can be converted to an iterator by accessing it from 0 to > len(adapter). Which is done by iter(). (or by __iter__, I don't know which > implementation would be "right") > ``` > iter(a) > #is equivalent to > (a[i] for i in range(len(a))) > ``` > For example any tuple is a valid adapter and any list can be easily > converted to one. > > Built-in adapter-generators: > "map" function should really return an adapter. The trouble with that is that map() already accepts any iterator. So you're asking for map to be able to return an iterator if given an iterator, or an adapter if given an adapter. That makes it quite complicated to use and reason about. In general, it's probably safest to just coalesce things to list when you need to: reversed(list(enumerate(a))) because otherwise there are many MANY questions left open. For example, in what order are the elements of a retrieved? with reversed(enumerate(a)) it's not clear, but if you force to list first, it is (and you know exactly when they're accessed too). ChrisA From list1 at tompassin.net Wed May 3 16:24:10 2023 From: list1 at tompassin.net (Thomas Passin) Date: Wed, 3 May 2023 16:24:10 -0400 Subject: An "adapter", superset of an iterator In-Reply-To: References: <536dd246-8029-47dd-1924-859b540b21cc@tompassin.net> Message-ID: <02fb7767-6b83-1e6f-5711-7fd214cfd196@tompassin.net> On 5/3/2023 3:46 PM, Oscar Benjamin wrote: > On Wed, 3 May 2023 at 18:52, Thomas Passin wrote: >> >> On 5/3/2023 5:45 AM, fedor tryfanau wrote: >>> I've been using python as a tool to solve competitive programming problems >>> for a while now and I've noticed a feature, python would benefit from >>> having. >>> Consider "reversed(enumerate(a))". This is a perfectly readable code, >>> except it's wrong in the current version of python. That's because >>> enumerate returns an iterator, but reversed can take only a sequence type. >> >> Depending on what you want to give and receive, enumerate(reversed(a)) >> will do the job here. Otherwise list() or tuple() can achieve some of >> the same things. > > I don't think that is equivalent to the intended behaviour: > > reversed(enumerate(a)) # zip(reversed(range(len(a))), reversed(a)) > enumerate(reversed(a)) # zip(range(len(a)), reversed(a)) I don't think we know the intended behavior here. The OP did not say what type of object should be returned. He only wanted an expression that would run. Apparently the result should be an enumeration of variable "a" but with "a" reversed. Is "a" supposed to be a sequence? An iterator? Presumably the result was expected to be an enumeration, which is to say an iterator, and enumerate(reversed(a)) would return an iterator. Perhaps the OP wants all methods/functions that operate on either sequences or iterators should be generalized to be able to operate on both. That doesn't sound unreasonable on the face of it, but I think that deeper study would uncover a lot of hard questions. There will also be a lot of edge cases to handle and get right. > In principle for a sequence input enumerate(a) could be something that > behaves like a sequence and therefore could be reiterated or reversed > etc. The enumerate(a).__reversed__ method could then delegate to > a.__reversed__ and a.__len__ if they exist. This could be confusing > though because the possible behaviour of enumerate(a) would be > different depending on the type of a. > > -- > Oscar From rosuav at gmail.com Wed May 3 17:51:08 2023 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 4 May 2023 07:51:08 +1000 Subject: An "adapter", superset of an iterator In-Reply-To: <02fb7767-6b83-1e6f-5711-7fd214cfd196@tompassin.net> References: <536dd246-8029-47dd-1924-859b540b21cc@tompassin.net> <02fb7767-6b83-1e6f-5711-7fd214cfd196@tompassin.net> Message-ID: On Thu, 4 May 2023 at 07:43, Thomas Passin wrote: > > On 5/3/2023 3:46 PM, Oscar Benjamin wrote: > > On Wed, 3 May 2023 at 18:52, Thomas Passin wrote: > >> > >> On 5/3/2023 5:45 AM, fedor tryfanau wrote: > >>> I've been using python as a tool to solve competitive programming problems > >>> for a while now and I've noticed a feature, python would benefit from > >>> having. > >>> Consider "reversed(enumerate(a))". This is a perfectly readable code, > >>> except it's wrong in the current version of python. That's because > >>> enumerate returns an iterator, but reversed can take only a sequence type. > >> > >> Depending on what you want to give and receive, enumerate(reversed(a)) > >> will do the job here. Otherwise list() or tuple() can achieve some of > >> the same things. > > > > I don't think that is equivalent to the intended behaviour: > > > > reversed(enumerate(a)) # zip(reversed(range(len(a))), reversed(a)) > > enumerate(reversed(a)) # zip(range(len(a)), reversed(a)) > > I don't think we know the intended behavior here. The OP did not say > what type of object should be returned. He only wanted an expression > that would run. Apparently the result should be an enumeration of > variable "a" but with "a" reversed. Is "a" supposed to be a sequence? > An iterator? Presumably the result was expected to be an enumeration, > which is to say an iterator, and enumerate(reversed(a)) would return an > iterator. The part you're probably missing here can be easily shown: >>> a = [10, 20, 30, 40, 50] >>> for i, n in enumerate(reversed(a)): ... print("E-R", i, n) ... E-R 0 50 E-R 1 40 E-R 2 30 E-R 3 20 E-R 4 10 >>> for i, n in reversed(list(enumerate(a))): ... print("R-E", i, n) ... R-E 4 50 R-E 3 40 R-E 2 30 R-E 1 20 R-E 0 10 So a closer equivalent would be: >>> for i, n in zip(reversed(range(len(a))), reversed(a)): ... print("Zip", i, n) ... Zip 4 50 Zip 3 40 Zip 2 30 Zip 1 20 Zip 0 10 Note that it's reversing both the indices and the values. ChrisA From avi.e.gross at gmail.com Wed May 3 19:54:42 2023 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Wed, 3 May 2023 19:54:42 -0400 Subject: An "adapter", superset of an iterator In-Reply-To: References: <536dd246-8029-47dd-1924-859b540b21cc@tompassin.net> Message-ID: <005f01d97e1a$a1b28120$e5178360$@gmail.com> As others have mentioned features added like this need careful examination not only at effects but costs. As I see it, several somewhat different ideas were raised and one of them strikes me oddly. The whole point of an iterable is to AVOID calculating the next item till needed. Otherwise, you can just make something like a list. To talk about random access to an iterable is a tad weird as it would mean you need to get the first N items and store them and return the Nth item value as well as maintain the remainder of the unused part of the iterable. Further requests already in the cache would be gotten from there and any beyond it would require iterating more and adding more to the cache. So say my iterator returns the first N primes or just those below 100. What should be the functionality if you request item 1,000? As for reversing it, that requires you to basically do list(iterable) and use it up. What if the iterable is infinite as in all the odd numbers? If you really want an iterable that return something like prime numbers below some level in reverse order, that can be done by changing the iterable to create them going downward and that would be a different iterator. But how easily could you make some iterators go backward? Fibonacci, maybe so. Other things perhaps not. But again, as noted, anything already in a list can be set up as an iterator that returns one item at a time from that list, including in reverse. There won't be much savings as the data structure inside would likely be spread out to take all the memory needed, albeit it may simplify the code to look like it was being delivered just in time. As with many things in python, rather than asking for a global solution that affects many others, sometimes in unexpected ways, it may be more reasonable to make your own patches to your code and use them in ways you can control. In the case being discussed, you simply need to create a generator function that accepts an iterator, converts it to a list in entirety, reverses the list (or deals with it from the end) and enters a loop where it yields one value at a time till done. This should work with all kinds of iterators and return what looks like an iterator without any changes to the language. Of course, I am likely to be missing something. And, certainly, there may already be modules doing things like the above or the opportunity for someone to create a module such as the itertools module with nifty little functions including factory functions. -----Original Message----- From: Python-list On Behalf Of Oscar Benjamin Sent: Wednesday, May 3, 2023 3:47 PM To: python-list at python.org Subject: Re: An "adapter", superset of an iterator On Wed, 3 May 2023 at 18:52, Thomas Passin wrote: > > On 5/3/2023 5:45 AM, fedor tryfanau wrote: > > I've been using python as a tool to solve competitive programming problems > > for a while now and I've noticed a feature, python would benefit from > > having. > > Consider "reversed(enumerate(a))". This is a perfectly readable code, > > except it's wrong in the current version of python. That's because > > enumerate returns an iterator, but reversed can take only a sequence type. > > Depending on what you want to give and receive, enumerate(reversed(a)) > will do the job here. Otherwise list() or tuple() can achieve some of > the same things. I don't think that is equivalent to the intended behaviour: reversed(enumerate(a)) # zip(reversed(range(len(a))), reversed(a)) enumerate(reversed(a)) # zip(range(len(a)), reversed(a)) In principle for a sequence input enumerate(a) could be something that behaves like a sequence and therefore could be reiterated or reversed etc. The enumerate(a).__reversed__ method could then delegate to a.__reversed__ and a.__len__ if they exist. This could be confusing though because the possible behaviour of enumerate(a) would be different depending on the type of a. -- Oscar -- https://mail.python.org/mailman/listinfo/python-list From greg.ewing at canterbury.ac.nz Wed May 3 20:01:01 2023 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Thu, 4 May 2023 12:01:01 +1200 Subject: An "adapter", superset of an iterator In-Reply-To: References: Message-ID: On 4/05/23 9:29 am, Chris Angelico wrote: > So > you're asking for map to be able to return an iterator if given an > iterator, or an adapter if given an adapter. That makes it quite > complicated to use and reason about. Also a bit slower, since it would need to inspect its argument and decide what to do with it. Currently it can just get on with its job and rely on duck typing to do the right thing. Maybe there could be a parallel set of functions "enumerated", "mapped", etc. that take sequences and return sequence views. Although that naming convention would suggest that reversed() itself should return a sequence view rather than an iterator. That would require restricting it to working on sequences, which would be an incompatible change. -- Greg From artie.ziff at gmail.com Wed May 3 20:52:00 2023 From: artie.ziff at gmail.com (Artie Ziff) Date: Wed, 3 May 2023 17:52:00 -0700 Subject: double bracket integer index in pandas; Is this a legal syntax In-Reply-To: References: Message-ID: I agree with your analysis, Cameron. The code came from a video course, "Pandas Data Analysis with Python Fundamentals" by Daniel Chen. I am curious why the author may have said this. To avoid attaching screenshots, I'll describe this section of the content. Perhaps someone can say, "oh that's how it used to work"... haha D.CHEN: "You can also subset the columns by number. If we wanted to get the first column from our data set, we would use zero": df = pandas.read_csv('./data/gapminder.tsv', sep='\t') >>> subset = df[[0]] >>> print(subset.head()) country 0 Afghanistan 1 Afghanistan 2 Afghanistan 3 Afghanistan 4 Afghanistan Data for the course: https://github.com/chendaniely/pandas_for_everyone.git "df[[0]]" is being described to the course student as selecting the first column of data. :-) I'll study that link. Thank you. From cs at cskk.id.au Wed May 3 22:29:45 2023 From: cs at cskk.id.au (Cameron Simpson) Date: Thu, 4 May 2023 12:29:45 +1000 Subject: double bracket integer index in pandas; Is this a legal syntax In-Reply-To: References: Message-ID: On 03May2023 17:52, Artie Ziff wrote: >The code came from a video course, "Pandas Data Analysis with Python >Fundamentals" by Daniel Chen. > >I am curious why the author may have said this. To avoid attaching >screenshots, I'll describe this section of the content. Perhaps someone can >say, "oh that's how it used to work"... haha Unlikely; Python indices (and by implication Pandas indices) have counted from 0 since forever. I suspect just a typo/braino. >D.CHEN: >"You can also subset the columns by number. If we wanted to get the first >column from our data set, we would use zero": > >df = pandas.read_csv('./data/gapminder.tsv', sep='\t') >>>> subset = df[[0]] >>>> print(subset.head()) > country >0 Afghanistan >1 Afghanistan >2 Afghanistan >3 Afghanistan >4 Afghanistan > >Data for the course: >https://github.com/chendaniely/pandas_for_everyone.git > >"df[[0]]" is being described to the course student as selecting the first >column of data. :-) Well, I would say it makes a new dataframe with just the first column. So: df[ 0 ] # spaces for clarity would (probably, need to check) return the Series for the first column. versus: df[ [0] ] # spaces for clarity makes a new dataframe with only the first column. A dataframe can be thought of as an array of Series (one per column). Cheers, Cameron Simpson From kevinmwilson1956 at yahoo.com Thu May 4 12:28:22 2023 From: kevinmwilson1956 at yahoo.com (Kevin M. Wilson) Date: Thu, 4 May 2023 16:28:22 +0000 (UTC) Subject: Disable 'style PEP' messages References: <2016933714.4132014.1683217702049.ref@mail.yahoo.com> Message-ID: <2016933714.4132014.1683217702049@mail.yahoo.com> Hi... How do I set Pycharm to find only syntax errors?!! "When you pass through the waters, I will be with you: and when you?pass through the rivers, they will not sweep over?you. When?you walk?through the fire, you will not be burned: the flames will not set you ablaze."? ? ? Isaiah 43:2 | | Virus-free.www.avg.com | From mats at wichmann.us Thu May 4 14:48:17 2023 From: mats at wichmann.us (Mats Wichmann) Date: Thu, 4 May 2023 12:48:17 -0600 Subject: Disable 'style PEP' messages In-Reply-To: <2016933714.4132014.1683217702049@mail.yahoo.com> References: <2016933714.4132014.1683217702049.ref@mail.yahoo.com> <2016933714.4132014.1683217702049@mail.yahoo.com> Message-ID: On 5/4/23 10:28, Kevin M. Wilson via Python-list wrote: > Hi... How do I set Pycharm to find only syntax errors?!! By configuring PyCharm the way you want. See PyCharm's documentation for how to do that. Hint: Settings -> Editor -> Code Style -> Inspections From PythonList at DancesWithMice.info Thu May 4 15:19:05 2023 From: PythonList at DancesWithMice.info (dn) Date: Fri, 5 May 2023 07:19:05 +1200 Subject: Disable 'style PEP' messages In-Reply-To: <2016933714.4132014.1683217702049@mail.yahoo.com> References: <2016933714.4132014.1683217702049.ref@mail.yahoo.com> <2016933714.4132014.1683217702049@mail.yahoo.com> Message-ID: <443c07e0-5496-8b0c-8d39-46214e44aae8@DancesWithMice.info> On 05/05/2023 04.28, Kevin M. Wilson via Python-list wrote: > Hi... How do I set Pycharm to find only syntax errors?!! Please review response to previous message re:configuring PyCharm's helpful features towards to coders and quality-coding... -- Regards, =dn From c.buhtz at posteo.jp Thu May 4 17:38:26 2023 From: c.buhtz at posteo.jp (c.buhtz at posteo.jp) Date: Thu, 04 May 2023 21:38:26 +0000 Subject: [pygettext] --package-name and --package-version unknown Message-ID: <27f92c2565e5256cc1263aa9a996550a@posteo.de> Hello, am I right to assume that "pygettext" is part of the official Python3 "package"? So it is OK to aks here? I do use pygettext to handle po and pot files. In the manpage I'm not able to find help about this. I would like to modify the header that pygettext does create in each po-file. How can I set the "Project-Id-Version"? With "xgettext" I would use the arguments "--package-name" and "--package-version" for this but they are unknown for "pygettext". Kind Christian From learn2program at gmail.com Thu May 4 19:54:30 2023 From: learn2program at gmail.com (Alan Gauld) Date: Fri, 5 May 2023 00:54:30 +0100 Subject: [pygettext] --package-name and --package-version unknown In-Reply-To: <27f92c2565e5256cc1263aa9a996550a@posteo.de> References: <27f92c2565e5256cc1263aa9a996550a@posteo.de> Message-ID: <31b8081a-68c4-70a9-9c1b-273854ef733c@yahoo.co.uk> On 04/05/2023 22:38, c.buhtz at posteo.jp wrote: > Hello, > > am I right to assume that "pygettext" is part of the official Python3 > "package"? So it is OK to aks here? > No it doesn't appear to be. It is not listed in the standard library. It is mentioned in the documentation for gettext which is part of the standard library. It does seem to be part of the Python i18n toolkit however. There are extensive comments in the .py file. https://github.com/python/cpython/tree/main/Tools/i18n/pygettext.py > I would like to modify the header that pygettext does create in each > po-file. Sorry, I've never used pygettext so can't help there. -- 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 aapost at idontexist.club Thu May 4 21:24:17 2023 From: aapost at idontexist.club (aapost) Date: Thu, 4 May 2023 21:24:17 -0400 Subject: [pygettext] --package-name and --package-version unknown In-Reply-To: References: <27f92c2565e5256cc1263aa9a996550a@posteo.de> Message-ID: On 5/4/23 17:38, c.buhtz at posteo.jp wrote: > am I right to assume that "pygettext" is part of the official Python3 > "package"? So it is OK to aks here? > > How can I set the "Project-Id-Version"? With "xgettext" I would use the > arguments "--package-name" and "--package-version" for this but they are > unknown for "pygettext". pygettext is deprecated since xgettext supports python now, so using xgettext is recommended. That being said, pygettext does not support the options, but it could be modified pretty easily. Untested but if you wanted to add that functionality in just create a modified pygettext.py with something like: link PACKAGE and VERSION to variables: pot_header = _('''\ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR ORGANIZATION # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: %(packagename)s %(packageversion)s\\n" "POT-Creation-Date: %(time)s\\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n" "Last-Translator: FULL NAME \\n" "Language-Team: LANGUAGE \\n" "MIME-Version: 1.0\\n" "Content-Type: text/plain; charset=%(charset)s\\n" "Content-Transfer-Encoding: %(encoding)s\\n" "Generated-By: pygettext.py %(version)s\\n" ''') add attributes to Options class: class Options: # constants GNU = 1 SOLARIS = 2 # defaults extractall = 0 # FIXME: currently this option has no effect at all. escape = 0 keywords = [] outpath = '' outfile = 'messages.pot' writelocations = 1 locationstyle = GNU verbose = 0 width = 78 excludefilename = '' docstrings = 0 nodocstrings = {} packagename = "PACKAGE" packageversion = "VERSION" modify option parsing for loop to look for new options: for opt, arg in opts: elif opt in ('--package-name',): options.packagename = arg elif opt in ('--package-version',): options.packageversion = arg grab those options when generating file output: def write(self, fp): options = self.__options packagename = options.packagename packageversion = options.packageversion timestamp = time.strftime('%Y-%m-%d %H:%M%z') encoding = fp.encoding if fp.encoding else 'UTF-8' print(pot_header % {'packagename': packagename, 'packageversion': packageversion, 'time': timestamp, 'version': __version__, 'charset': encoding, 'encoding': '8bit'}, file=fp) (did not test, so might be a bug or two) From kevinmwilson1956 at yahoo.com Thu May 4 22:00:28 2023 From: kevinmwilson1956 at yahoo.com (Kevin M. Wilson) Date: Fri, 5 May 2023 02:00:28 +0000 (UTC) Subject: Three (3) >>> in the debug screen of PyCharm... Que Es over?!! References: <1571964685.481588.1683252028037.ref@mail.yahoo.com> Message-ID: <1571964685.481588.1683252028037@mail.yahoo.com> "When you pass through the waters, I will be with you: and when you?pass through the rivers, they will not sweep over?you. When?you walk?through the fire, you will not be burned: the flames will not set you ablaze."? ? ? Isaiah 43:2 | | Virus-free.www.avg.com | From c.buhtz at posteo.jp Fri May 5 04:39:54 2023 From: c.buhtz at posteo.jp (c.buhtz at posteo.jp) Date: Fri, 05 May 2023 08:39:54 +0000 Subject: [pygettext] --package-name and --package-version unknown In-Reply-To: References: <27f92c2565e5256cc1263aa9a996550a@posteo.de> Message-ID: <4083df1963eba88c54c833c7c2f04e34@posteo.de> Thanks for the answer. Am 05.05.2023 03:24 schrieb aapost: > pygettext is deprecated since xgettext supports python now, so using > xgettext is recommended. If this is the official case then it should be mentioned in the python docs. The 3.11 docs still tell about pygettext and xgettext and don't recommend one of it. From aapost at idontexist.club Fri May 5 04:56:22 2023 From: aapost at idontexist.club (aapost) Date: Fri, 5 May 2023 04:56:22 -0400 Subject: [pygettext] --package-name and --package-version unknown In-Reply-To: References: <27f92c2565e5256cc1263aa9a996550a@posteo.de> <4083df1963eba88c54c833c7c2f04e34@posteo.de> Message-ID: On 5/5/23 04:39, c.buhtz at posteo.jp wrote: > Thanks for the answer. > > Am 05.05.2023 03:24 schrieb aapost: >> pygettext is deprecated since xgettext supports python now, so using >> xgettext is recommended. > > If this is the official case then it should be mentioned in the python > docs. The 3.11 docs still tell about pygettext and xgettext and don't > recommend one of it. Yep, no disagreement. A lot of things 'should' be though, and technically it is (which docs being the key, lol): $man pygettext PYGETTEXT(1) General Commands Manual PYGETTEXT(1) NAME pygettext - Python equivalent of xgettext(1) SYNOPSIS pygettext [OPTIONS] INPUTFILE ... DESCRIPTION pygettext is deprecated. The current version of xgettext supports many languages, including Python. pygettext uses Python's standard tokenize module to scan Python source code, generating .pot files identical to what GNU xgettext generates for C and C++ code. From there, the standard GNU tools can be used. pygettext searches only for _() by default, even though GNU xgettext recognizes the following keywords: gettext, dgettext, dcgettext, and gettext_noop. See the -k/--keyword flag below for how to augment this. (I have never used either, I just spent a few minutes trying to be helpful =P) From aapost at idontexist.club Fri May 5 05:12:52 2023 From: aapost at idontexist.club (aapost) Date: Fri, 5 May 2023 05:12:52 -0400 Subject: [pygettext] --package-name and --package-version unknown In-Reply-To: References: <27f92c2565e5256cc1263aa9a996550a@posteo.de> <4083df1963eba88c54c833c7c2f04e34@posteo.de> Message-ID: On 5/5/23 04:39, c.buhtz at posteo.jp wrote: > That being said, the git repo linked earlier has accepted commits to that file earlier this year. So read in to that what you will *shrugs* From cl at isbd.net Sat May 6 06:13:03 2023 From: cl at isbd.net (Chris Green) Date: Sat, 6 May 2023 11:13:03 +0100 Subject: Problem with accented characters in mailbox.Maildir() Message-ID: I have a custom mail filter in python that uses the mailbox package to open a mail message and give me access to the headers. So I have the following code to open each mail message:- # # # Read the message from standard input and make a message object from it # msg = mailbox.MaildirMessage(sys.stdin.buffer.read()) and then later I have (among many other bits and pieces):- # # # test for string in Subject: # if searchTxt in str(msg.get("subject", "unknown")): do various things This works exactly as intended most of the time but occasionally a message whose subject should match the test is missed. I have just realised when this happens, it's when the Subject: has accented characters in it (this is from a mailing list about canals in France). So, for example, the latest case of this happening has:- Subject: aka Marne ? la Sa?ne (Waterways Continental Europe) where the searchTxt in the code above is "Waterways Continental Europe". Is there any way I can work round this issue? E.g. is there a way to strip out all extended characters from a string? Or maybe it's msg.get() that isn't managing to handle the accented string correctly? Yes, I know that accented characters probably aren't allowed in Subject: but I'm not going to get that changed! :-) -- Chris Green ? From nospam at please.ty Sat May 6 07:38:49 2023 From: nospam at please.ty (jak) Date: Sat, 6 May 2023 13:38:49 +0200 Subject: Problem with accented characters in mailbox.Maildir() In-Reply-To: References: Message-ID: Chris Green ha scritto: > I have a custom mail filter in python that uses the mailbox package to > open a mail message and give me access to the headers. > > So I have the following code to open each mail message:- > > # > # > # Read the message from standard input and make a message object from it > # > msg = mailbox.MaildirMessage(sys.stdin.buffer.read()) > > and then later I have (among many other bits and pieces):- > > # > # > # test for string in Subject: > # > if searchTxt in str(msg.get("subject", "unknown")): > do > various > things > > > This works exactly as intended most of the time but occasionally a > message whose subject should match the test is missed. I have just > realised when this happens, it's when the Subject: has accented > characters in it (this is from a mailing list about canals in France). > > So, for example, the latest case of this happening has:- > > Subject: aka Marne ? la Sa?ne (Waterways Continental Europe) > > where the searchTxt in the code above is "Waterways Continental Europe". > > > Is there any way I can work round this issue? E.g. is there a way to > strip out all extended characters from a string? Or maybe it's > msg.get() that isn't managing to handle the accented string correctly? > > Yes, I know that accented characters probably aren't allowed in > Subject: but I'm not going to get that changed! :-) > > Hi, you could try extracting the "Content-Type:charset" and then using it for subject conversion: subj = str(raw_subj, encoding='...') From cl at isbd.net Sat May 6 07:51:37 2023 From: cl at isbd.net (Chris Green) Date: Sat, 6 May 2023 12:51:37 +0100 Subject: Problem with accented characters in mailbox.Maildir() References: Message-ID: <9jrhij-o0st1.ln1@esprimo.zbmc.eu> A bit more information, msg.get("subject", "unknown") does return a string, as follows:- Subject: =?utf-8?Q?aka_Marne_=C3=A0_la_Sa=C3=B4ne_(Waterways_Continental_Europe)?= So it's the 'searchTxt in msg.get("subject", "unknown")' that's failing. I.e. for some reason 'in' isn't working when the searched string has utf-8 characters. Surely there's a way to handle this. -- Chris Green ? From cl at isbd.net Sat May 6 08:46:55 2023 From: cl at isbd.net (Chris Green) Date: Sat, 6 May 2023 13:46:55 +0100 Subject: Problem with accented characters in mailbox.Maildir() References: <9jrhij-o0st1.ln1@esprimo.zbmc.eu> Message-ID: Chris Green wrote: > A bit more information, msg.get("subject", "unknown") does return a > string, as follows:- > > Subject: =?utf-8?Q?aka_Marne_=C3=A0_la_Sa=C3=B4ne_(Waterways_Continental_Europe)?= > > So it's the 'searchTxt in msg.get("subject", "unknown")' that's > failing. I.e. for some reason 'in' isn't working when the searched > string has utf-8 characters. > > Surely there's a way to handle this. > ... and of course I now see the issue! The Subject: with utf-8 characters in it gets spaces changed to underscores. So searching for '(Waterways Continental Europe)' fails. I'll either need to test for both versions of the string or I'll need to change underscores to spaces in the Subject: returned by msg.get(). It's a long enough string that I'm searching for that I won't get any false positives. Sorry for the noise everyone, it's a typical case of explaining the problem shows one how to fix it! :-) -- Chris Green ? From cl at isbd.net Sat May 6 09:50:40 2023 From: cl at isbd.net (Chris Green) Date: Sat, 6 May 2023 14:50:40 +0100 Subject: What do these '=?utf-8?' sequences mean in python? Message-ID: I'm having a real hard time trying to do anything to a string (?) returned by mailbox.MaildirMessage.get(). I'm extracting the Subject: header from a message and, if I write what it returns to a log file using the python logging module what I see in the log file (when the Subject: has non-ASCII characters in it) is:- =?utf-8?Q?aka_Marne_=C3=A0_la_Sa=C3=B4ne_(Waterways_Continental_Europe)?= Whatever I try I am unable to change the underscore characters in the above string back to spaces. So, what do those =?utf-8? and ?= sequences mean? Are they part of the string or are they wrapped around the string on output as a way to show that it's utf-8 encoded? If I have the string in a variable how do I replace the underscores with spaces? Simply doing "subject.replace('_', ' ')" doesn't work, nothing happens at all. All I really want to do is throw the non-ASCII characters away as the string I'm trying to match in the subject is guaranteed to be ASCII. -- Chris Green ? From nospam at please.ty Sat May 6 10:27:04 2023 From: nospam at please.ty (jak) Date: Sat, 6 May 2023 16:27:04 +0200 Subject: Problem with accented characters in mailbox.Maildir() In-Reply-To: References: <9jrhij-o0st1.ln1@esprimo.zbmc.eu> Message-ID: Chris Green ha scritto: > Chris Green wrote: >> A bit more information, msg.get("subject", "unknown") does return a >> string, as follows:- >> >> Subject: =?utf-8?Q?aka_Marne_=C3=A0_la_Sa=C3=B4ne_(Waterways_Continental_Europe)?= >> >> So it's the 'searchTxt in msg.get("subject", "unknown")' that's >> failing. I.e. for some reason 'in' isn't working when the searched >> string has utf-8 characters. >> >> Surely there's a way to handle this. >> > ... and of course I now see the issue! The Subject: with utf-8 > characters in it gets spaces changed to underscores. So searching for > '(Waterways Continental Europe)' fails. > > I'll either need to test for both versions of the string or I'll need > to change underscores to spaces in the Subject: returned by msg.get(). > It's a long enough string that I'm searching for that I won't get any > false positives. > > > Sorry for the noise everyone, it's a typical case of explaining the > problem shows one how to fix it! :-) > This is probably what you need: import email.header raw_subj = '=?utf-8?Q?aka_Marne_=C3=A0_la_Sa=C3=B4ne_(Waterways_Continental_Europe)?=' subj = email.header.decode_header(raw_subj)[0] subj[0].decode(subj[1]) 'aka Marne ? la Sa?ne (Waterways Continental Europe)' From cl at isbd.net Sat May 6 10:58:15 2023 From: cl at isbd.net (Chris Green) Date: Sat, 6 May 2023 15:58:15 +0100 Subject: What do these '=?utf-8?' sequences mean in python? References: Message-ID: <7h6iij-nniu1.ln1@esprimo.zbmc.eu> Chris Green wrote: > I'm having a real hard time trying to do anything to a string (?) > returned by mailbox.MaildirMessage.get(). > What a twit I am :-) Strings are immutable, I have to do:- newstring = oldstring.replace("_", " ") Job done! -- Chris Green ? From pkpearson at nowhere.invalid Sat May 6 11:10:05 2023 From: pkpearson at nowhere.invalid (Peter Pearson) Date: 6 May 2023 15:10:05 GMT Subject: What do these '=?utf-8?' sequences mean in python? References: Message-ID: On Sat, 6 May 2023 14:50:40 +0100, Chris Green wrote: [snip] > So, what do those =?utf-8? and ?= sequences mean? Are they part of > the string or are they wrapped around the string on output as a way to > show that it's utf-8 encoded? Yes, "=?utf-8?" signals "MIME header encoding". I've only blundered about briefly in this area, but I think you need to make sure that all header values you work with have been converted to UTF-8 before proceeding. Here's the code that seemed to work for me: def mime_decode_single(pair): """Decode a single (bytestring, charset) pair. """ b, charset = pair result = b if isinstance(b, str) else b.decode( charset if charset else "utf-8") return result def mime_decode(s): """Decode a MIME-header-encoded character string. """ decoded_pairs = email.header.decode_header(s) return "".join(mime_decode_single(d) for d in decoded_pairs) -- To email me, substitute nowhere->runbox, invalid->com. From nospam at please.ty Sat May 6 12:27:23 2023 From: nospam at please.ty (jak) Date: Sat, 6 May 2023 18:27:23 +0200 Subject: What do these '=?utf-8?' sequences mean in python? In-Reply-To: References: Message-ID: Peter Pearson ha scritto: > On Sat, 6 May 2023 14:50:40 +0100, Chris Green wrote: > [snip] >> So, what do those =?utf-8? and ?= sequences mean? Are they part of >> the string or are they wrapped around the string on output as a way to >> show that it's utf-8 encoded? > > Yes, "=?utf-8?" signals "MIME header encoding". > > I've only blundered about briefly in this area, but I think you > need to make sure that all header values you work with have been > converted to UTF-8 before proceeding. > Here's the code that seemed to work for me: > > def mime_decode_single(pair): > """Decode a single (bytestring, charset) pair. > """ > b, charset = pair > result = b if isinstance(b, str) else b.decode( > charset if charset else "utf-8") > return result > > def mime_decode(s): > """Decode a MIME-header-encoded character string. > """ > decoded_pairs = email.header.decode_header(s) > return "".join(mime_decode_single(d) for d in decoded_pairs) > > > HI, You could also use make_header: from email.header import decode_header, make_header print(make_header(decode_header( subject ))) From Keith.S.Thompson+u at gmail.com Sun May 7 20:53:04 2023 From: Keith.S.Thompson+u at gmail.com (Keith Thompson) Date: Sun, 07 May 2023 17:53:04 -0700 Subject: What do these '=?utf-8?' sequences mean in python? References: <7h6iij-nniu1.ln1@esprimo.zbmc.eu> Message-ID: <87fs87bq4v.fsf@nosuchdomain.example.com> Chris Green writes: > Chris Green wrote: >> I'm having a real hard time trying to do anything to a string (?) >> returned by mailbox.MaildirMessage.get(). >> > What a twit I am :-) > > Strings are immutable, I have to do:- > > newstring = oldstring.replace("_", " ") > > Job done! Not necessarily. The subject in the original article was: =?utf-8?Q?aka_Marne_=C3=A0_la_Sa=C3=B4ne_(Waterways_Continental_Europe)?= That's some kind of MIME encoding. Just replacing underscores by spaces won't necessarily give you anything meaningful. (What if there are actual underscores in the original subject line?) You should probably apply some kind of MIME-specific decoding. (I don't have a specific suggestion for how to do that.) -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u at gmail.com Working, but not speaking, for XCOM Labs void Void(void) { Void(); } /* The recursive call of the void */ From cl at isbd.net Mon May 8 04:45:43 2023 From: cl at isbd.net (Chris Green) Date: Mon, 8 May 2023 09:45:43 +0100 Subject: What do these '=?utf-8?' sequences mean in python? References: <7h6iij-nniu1.ln1@esprimo.zbmc.eu> <87fs87bq4v.fsf@nosuchdomain.example.com> Message-ID: Keith Thompson wrote: > Chris Green writes: > > Chris Green wrote: > >> I'm having a real hard time trying to do anything to a string (?) > >> returned by mailbox.MaildirMessage.get(). > >> > > What a twit I am :-) > > > > Strings are immutable, I have to do:- > > > > newstring = oldstring.replace("_", " ") > > > > Job done! > > Not necessarily. > > The subject in the original article was: > =?utf-8?Q?aka_Marne_=C3=A0_la_Sa=C3=B4ne_(Waterways_Continental_Europe)?= > > That's some kind of MIME encoding. Just replacing underscores by spaces > won't necessarily give you anything meaningful. (What if there are > actual underscores in the original subject line?) > > You should probably apply some kind of MIME-specific decoding. (I don't > have a specific suggestion for how to do that.) > Yes, OK, but my problem was that my filter looks for the string "Waterways Continental Europe" in the message Subject: to route the message to the appropriate mailbox. When the Subject: has accents the string becomes "Waterways_Continental_Europe" and thus the match fails. Simply changing all underscores back to spaces makes my test for "Waterways Continental Europe" work. The changed Subject: line gets thrown away after the test so I don't care about anything else getting changed. (When there are no accented characters in the Subject: the string is "Waterways Continental Europe" so I can't easily change the search text. I guess I could use an RE.) -- Chris Green ? From nospam at please.ty Mon May 8 06:19:01 2023 From: nospam at please.ty (jak) Date: Mon, 8 May 2023 12:19:01 +0200 Subject: What do these '=?utf-8?' sequences mean in python? In-Reply-To: References: <7h6iij-nniu1.ln1@esprimo.zbmc.eu> <87fs87bq4v.fsf@nosuchdomain.example.com> Message-ID: Chris Green ha scritto: > Keith Thompson wrote: >> Chris Green writes: >>> Chris Green wrote: >>>> I'm having a real hard time trying to do anything to a string (?) >>>> returned by mailbox.MaildirMessage.get(). >>>> >>> What a twit I am :-) >>> >>> Strings are immutable, I have to do:- >>> >>> newstring = oldstring.replace("_", " ") >>> >>> Job done! >> >> Not necessarily. >> >> The subject in the original article was: >> =?utf-8?Q?aka_Marne_=C3=A0_la_Sa=C3=B4ne_(Waterways_Continental_Europe)?= >> >> That's some kind of MIME encoding. Just replacing underscores by spaces >> won't necessarily give you anything meaningful. (What if there are >> actual underscores in the original subject line?) >> >> You should probably apply some kind of MIME-specific decoding. (I don't >> have a specific suggestion for how to do that.) >> > Yes, OK, but my problem was that my filter looks for the string > "Waterways Continental Europe" in the message Subject: to route the > message to the appropriate mailbox. When the Subject: has accents the > string becomes "Waterways_Continental_Europe" and thus the match > fails. Simply changing all underscores back to spaces makes my test > for "Waterways Continental Europe" work. The changed Subject: line > gets thrown away after the test so I don't care about anything else > getting changed. > > (When there are no accented characters in the Subject: the string is > "Waterways Continental Europe" so I can't easily change the search > text. I guess I could use an RE.) > In reality you should also take into account the fact that if the header contains a 'b' instead of a 'q' as a penultimate character, then the rest of the package is converted on the basis64 "=?utf-8?Q?" --> "=?utf-8?B?" From dieter at handshake.de Mon May 8 12:37:17 2023 From: dieter at handshake.de (Dieter Maurer) Date: Mon, 8 May 2023 18:37:17 +0200 Subject: What do these '=?utf-8?' sequences mean in python? In-Reply-To: <7h6iij-nniu1.ln1@esprimo.zbmc.eu> References: <7h6iij-nniu1.ln1@esprimo.zbmc.eu> Message-ID: <25689.9533.858453.692569@ixdm.fritz.box> Chris Green wrote at 2023-5-6 15:58 +0100: >Chris Green wrote: >> I'm having a real hard time trying to do anything to a string (?) >> returned by mailbox.MaildirMessage.get(). >> >What a twit I am :-) > >Strings are immutable, I have to do:- > > newstring = oldstring.replace("_", " ") The solution based on `email.Header` proposed by `jak` is better. From hjp-python at hjp.at Mon May 8 14:36:18 2023 From: hjp-python at hjp.at (Peter J. Holzer) Date: Mon, 8 May 2023 20:36:18 +0200 Subject: Problem with accented characters in mailbox.Maildir() In-Reply-To: References: <9jrhij-o0st1.ln1@esprimo.zbmc.eu> Message-ID: <20230508183618.iy3r67ifxshhe5kx@hjp.at> On 2023-05-06 16:27:04 +0200, jak wrote: > Chris Green ha scritto: > > Chris Green wrote: > > > A bit more information, msg.get("subject", "unknown") does return a > > > string, as follows:- > > > > > > Subject: =?utf-8?Q?aka_Marne_=C3=A0_la_Sa=C3=B4ne_(Waterways_Continental_Europe)?= [...] > > ... and of course I now see the issue! The Subject: with utf-8 > > characters in it gets spaces changed to underscores. So searching for > > '(Waterways Continental Europe)' fails. > > > > I'll either need to test for both versions of the string or I'll need > > to change underscores to spaces in the Subject: returned by msg.get(). You need to decode the Subject properly. Unfortunately the Python email module doesn't do that for you automatically. But it does provide the necessary tools. Don't roll your own unless you've read and understood the relevant RFCs. > > This is probably what you need: > > import email.header > > raw_subj = > '=?utf-8?Q?aka_Marne_=C3=A0_la_Sa=C3=B4ne_(Waterways_Continental_Europe)?=' > > subj = email.header.decode_header(raw_subj)[0] > > subj[0].decode(subj[1]) > > 'aka Marne ? la Sa?ne (Waterways Continental Europe)' You are an the right track, but that works only because the example exists only of a single encoded word. This is not always the case (and indeed not what the RFC recommends). email.header.decode_header returns a *list* of chunks and you have to process and concatenate all of them. Here is a snippet from a mail to html converter I wrote a few years ago: def decode_rfc2047(s): if s is None: return None r = "" for chunk in email.header.decode_header(s): if chunk[1]: try: r += chunk[0].decode(chunk[1]) except LookupError: r += chunk[0].decode("windows-1252") except UnicodeDecodeError: r += chunk[0].decode("windows-1252") elif type(chunk[0]) == bytes: r += chunk[0].decode('us-ascii') else: r += chunk[0] return r (this is maybe a bit more forgiving than the OP needs, but I had to deal with malformed mails) I do have to say that Python is extraordinarily clumsy in this regard. 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 nospam at please.ty Mon May 8 17:02:18 2023 From: nospam at please.ty (jak) Date: Mon, 8 May 2023 23:02:18 +0200 Subject: Problem with accented characters in mailbox.Maildir() In-Reply-To: References: <9jrhij-o0st1.ln1@esprimo.zbmc.eu> <20230508183618.iy3r67ifxshhe5kx@hjp.at> Message-ID: Peter J. Holzer ha scritto: > On 2023-05-06 16:27:04 +0200, jak wrote: >> Chris Green ha scritto: >>> Chris Green wrote: >>>> A bit more information, msg.get("subject", "unknown") does return a >>>> string, as follows:- >>>> >>>> Subject: =?utf-8?Q?aka_Marne_=C3=A0_la_Sa=C3=B4ne_(Waterways_Continental_Europe)?= > [...] >>> ... and of course I now see the issue! The Subject: with utf-8 >>> characters in it gets spaces changed to underscores. So searching for >>> '(Waterways Continental Europe)' fails. >>> >>> I'll either need to test for both versions of the string or I'll need >>> to change underscores to spaces in the Subject: returned by msg.get(). > > You need to decode the Subject properly. Unfortunately the Python email > module doesn't do that for you automatically. But it does provide the > necessary tools. Don't roll your own unless you've read and understood > the relevant RFCs. > >> >> This is probably what you need: >> >> import email.header >> >> raw_subj = >> '=?utf-8?Q?aka_Marne_=C3=A0_la_Sa=C3=B4ne_(Waterways_Continental_Europe)?=' >> >> subj = email.header.decode_header(raw_subj)[0] >> >> subj[0].decode(subj[1]) >> >> 'aka Marne ? la Sa?ne (Waterways Continental Europe)' > > You are an the right track, but that works only because the example > exists only of a single encoded word. This is not always the case (and > indeed not what the RFC recommends). > > email.header.decode_header returns a *list* of chunks and you have to > process and concatenate all of them. > > Here is a snippet from a mail to html converter I wrote a few years ago: > > def decode_rfc2047(s): > if s is None: > return None > r = "" > for chunk in email.header.decode_header(s): > if chunk[1]: > try: > r += chunk[0].decode(chunk[1]) > except LookupError: > r += chunk[0].decode("windows-1252") > except UnicodeDecodeError: > r += chunk[0].decode("windows-1252") > elif type(chunk[0]) == bytes: > r += chunk[0].decode('us-ascii') > else: > r += chunk[0] > return r > > (this is maybe a bit more forgiving than the OP needs, but I had to deal > with malformed mails) > > I do have to say that Python is extraordinarily clumsy in this regard. > > hp > Thanks for the reply. In fact, I gave that answer because I did not understand what the OP wanted to achieve. In addition, the OP opened a second thread on the similar topic in which I gave a more correct answer (subject: "What do these '=?utf-8?' sequences mean in python?", date: "Sat, 6 May 2023 14:50:40 UTC"). I was interested in this thread because a few years ago I wrote a program in C that sent, via email, the log file of an application in the event that it crashed and I had created the attachment based64, however at the time I did not know of the RFC2047 relating to the subject. In addition, investigating the needs of the OP, I discovered that the MAME is not the only format used to compose the subject. I found an example in a thread of same days ago where the subject contained Arabic text (sender: "Uhrda education ", date: "Wed, 03 May 2023 00:18:14 UTC"). This is the raw version of the subject: =?UTF-8?B?2LTZh9in2K/YqSDYo9iu2LXYp9im2Yog2K7Yr9mF2Kkg2LnZhdmE2KfYoSDZhdi52KrZhQ==?= =?UTF-8?B?2K8gI9in2YjZhtmE2KfZitmGINio2LHYs9mI2YUg2YXYrtmB2LbYqSDYrtmE2KfZhCDYtNmH2LEg2YU=?= =?UTF-8?B?2KfZitmIMjAyMyDZhNmE2KfYs9iq2YHYs9in2LEg2YjYp9iq2LMgLyAwMDIwMTAwOTMwNjExMQ==?= As you can see, the penultimate letter of the header is not a 'q' as in the OP message but it is a 'b' and the body of the message is covered according to the base64. This made me think that a library could not delegate to the programmer the burden of managing all these exceptions, then I have further investigated to discover that the library also provides the conversion function beyond that of coding and this makes our labors vain: ---------- from email.header import decode_header, make_header subject = make_header(decode_header( raw_subject ))) ---------- This line of code correctly converts the message of the OP and also the one with the text in Arabic. I greet you with cordiality. From cs at cskk.id.au Mon May 8 21:38:55 2023 From: cs at cskk.id.au (Cameron Simpson) Date: Tue, 9 May 2023 11:38:55 +1000 Subject: What do these '=?utf-8?' sequences mean in python? In-Reply-To: References: Message-ID: On 08May2023 12:19, jak wrote: >In reality you should also take into account the fact that if the >header >contains a 'b' instead of a 'q' as a penultimate character, then the >rest of the package is converted on the basis64 > >"=?utf-8?Q?" --> "=?utf-8?B?" Aye. Specification: https://datatracker.ietf.org/doc/html/rfc2047 You should reach for jak's suggested email.header suggestion _before_ parsing the subject line. Details: https://docs.python.org/3/library/email.header.html#module-email.header Cheers, Cameron Simpson From tony.flury at btinternet.com Tue May 9 02:45:34 2023 From: tony.flury at btinternet.com (Tony Flury) Date: Tue, 9 May 2023 07:45:34 +0100 Subject: Python-pickle error In-Reply-To: References: Message-ID: <2b885cb4-8917-143b-b543-382133514d3f@btinternet.com> Charles, by your own admission, you deleted your pkl file, And your code doesn't write that pkl file (pickle.dumps(...) doesn't write a file it creates a new string and at no point will it write to the file : What you need is this : import pickle number=2 my_pickled_object=pickle.dumps(number) with open('file.pkl', 'w') as file: file.write(my_pickled_object) print("this is my pickled object",{my_pickled_object},) del number # you can do this if you really want to test pickle. with open('file.pkl', 'r') as file: number=pickle.load(file) my_unpickled_object=pickle.loads(my_pickled_object) print("this is my unpickled object",{my_unpickled_object},) Note :? that the whole point of the pickle format is that you don't need to open and write/read files in binary format. On 19/04/2023 17:14, charles wiewiora wrote: > Hello, > I am experincing problems with the pickle moducle > the folowing code was working before, > > import pickle > number=2 > my_pickeld_object=pickle.dumps(number) > print("this is my pickled object",{my_pickeld_object},) > with open('file.pkl', 'rb') as file: > number=pickle.load(file) > my_unpickeled_object=pickle.loads(my_pickeld_object) > print("this is my unpickeled object",{my_unpickeled_object},) > > but now i get error > > Traceback (most recent call last): > File "C:\Users\lukwi\Desktop\python\tester2.py", line 5, in > with open('file.pkl', 'rb') as file: > FileNotFoundError: [Errno 2] No such file or directory: 'file.pkl' > > im get this problem after this, > a .pkl came into my Python script files > i though this could be a spare file made from python becauce i was doing this first, > > import pickle > number=2 > my_pickeld_object=pickle.dumps(number) > print("this is my pickled object",{my_pickeld_object},) > with open('file.pkl', 'rb') as file: > number=pickle.load(file) > > so i stupidly deleted the file > > do you know how to fix this? > i reinstalled it but it didn't work > this is on widnows and on version 3.11.3 on python > > thank you -- Anthony Flury email : anthony.flury at btinternet.com From koinerhorst6 at gmail.com Tue May 9 14:13:08 2023 From: koinerhorst6 at gmail.com (Horst Koiner) Date: Tue, 9 May 2023 11:13:08 -0700 (PDT) Subject: Do subprocess.PIPE and subprocess.STDOUT sametime Message-ID: <40d57d83-c868-4851-a01a-c5608f4924b1n@googlegroups.com> Hi @all, i'm running a program which is still in development with subprocess.run (Python version 3.10), further i need to capture the output of the program in a python variable. The program itself runs about 2 minutes, but it can also freeze in case of new bugs. For production i run the program with stdout=subprocess.PIPE and i can fetch than the output later. For just testing if the program works, i run with stdout=subprocess.STDOUT and I see all program output on the console, but my program afterwards crashes since there is nothing captured in the python variable. So I think I need to have the functionality of subprocess.PIPE and subprcess.STDOUT sametime. What I tried until now: 1. Poll the the output and use Popen instead: # Start the subprocess process = subprocess.Popen(['./test.sh'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) captured_output = b'' process_running = True while process_running: process_running = (process.poll() is not None) for pipe in [ process.stdout, process.stderr ]: while line := pipe.readline(): print(line) captured_output += line print(captured_output) return_code = process.returncode => But this is discouraged by the python doc, since it says that polling this way is prone to deadlocks. Instead it proposes the use of the communicate() function. 2. Use communicate() with timeout. => This works not at all since when the timeout occurs an exception is thrown and communicate returns at all. 3. Use threading instead => For being that simple and universal like subprocess you will more or less reimplement subprocess with threading, like its done in subprocess.py. Just for a debug output the effort is much to high. ####################################################### Do you have further ideas for implementing such a behavior? Do you think that a feature request should be done of I'm omitting something obvious? Thanks you in advance for your suggestions, Horst. From mats at wichmann.us Tue May 9 15:05:39 2023 From: mats at wichmann.us (Mats Wichmann) Date: Tue, 9 May 2023 13:05:39 -0600 Subject: Do subprocess.PIPE and subprocess.STDOUT sametime In-Reply-To: <40d57d83-c868-4851-a01a-c5608f4924b1n@googlegroups.com> References: <40d57d83-c868-4851-a01a-c5608f4924b1n@googlegroups.com> Message-ID: <9da63d82-55d2-bb0c-33d2-10b5d28a8dc8@wichmann.us> On 5/9/23 12:13, Horst Koiner wrote: > Hi @all, > i'm running a program which is still in development with subprocess.run (Python version 3.10), further i need to capture the output of the program in a python variable. The program itself runs about 2 minutes, but it can also freeze in case of new bugs. > > For production i run the program with stdout=subprocess.PIPE and i can fetch than the output later. For just testing if the program works, i run with stdout=subprocess.STDOUT and I see all program output on the console, but my program afterwards crashes since there is nothing captured in the python variable. So I think I need to have the functionality of subprocess.PIPE and subprcess.STDOUT sametime. I'm not sure you quite understood what subprocess.STDOUT is for. If you say nothing stdout is not captured. STDOUT is used as a value for stderr to mean send it the same place as stdout, which is useful if you set stdout to something unusual, then you don't have to retype it if you want stderr going the same place. The subprocess module, afaik, doesn't even have a case for stdout=STDOUT. > > What I tried until now: > 1. Poll the the output and use Popen instead: > > # Start the subprocess > process = subprocess.Popen(['./test.sh'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) > > captured_output = b'' > process_running = True > while process_running: > process_running = (process.poll() is not None) > for pipe in [ process.stdout, process.stderr ]: > while line := pipe.readline(): > print(line) > captured_output += line > > print(captured_output) > return_code = process.returncode > > => But this is discouraged by the python doc, since it says that polling this way is prone to deadlocks. Instead it proposes the use of the communicate() function. > > 2. Use communicate() with timeout. > => This works not at all since when the timeout occurs an exception is thrown and communicate returns at all. Well, sure ... if you set timeout, then you need to be prepared to catch the TimeoutExpired exception and deal with it. That should be entirely normal. > > 3. Use threading instead > => For being that simple and universal like subprocess you will more or less reimplement subprocess with threading, like its done in subprocess.py. Just for a debug output the effort is much to high. Not sure I get what this is asking/suggesting. If you don't want to wait for the subprocess to run, you can use async - that's been fully implemented. https://docs.python.org/3/library/asyncio-subprocess.html From list1 at tompassin.net Tue May 9 15:39:19 2023 From: list1 at tompassin.net (Thomas Passin) Date: Tue, 9 May 2023 15:39:19 -0400 Subject: Do subprocess.PIPE and subprocess.STDOUT sametime In-Reply-To: <40d57d83-c868-4851-a01a-c5608f4924b1n@googlegroups.com> References: <40d57d83-c868-4851-a01a-c5608f4924b1n@googlegroups.com> Message-ID: On 5/9/2023 2:13 PM, Horst Koiner wrote: > Hi @all, > i'm running a program which is still in development with subprocess.run (Python version 3.10), further i need to capture the output of the program in a python variable. The program itself runs about 2 minutes, but it can also freeze in case of new bugs. > > For production i run the program with stdout=subprocess.PIPE and i can fetch than the output later. For just testing if the program works, i run with stdout=subprocess.STDOUT and I see all program output on the console, but my program afterwards crashes since there is nothing captured in the python variable. So I think I need to have the functionality of subprocess.PIPE and subprcess.STDOUT sametime. > > What I tried until now: > 1. Poll the the output and use Popen instead: > > # Start the subprocess > process = subprocess.Popen(['./test.sh'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) > > captured_output = b'' > process_running = True > while process_running: > process_running = (process.poll() is not None) > for pipe in [ process.stdout, process.stderr ]: > while line := pipe.readline(): > print(line) > captured_output += line > > print(captured_output) > return_code = process.returncode > > => But this is discouraged by the python doc, since it says that polling this way is prone to deadlocks. Instead it proposes the use of the communicate() function. > > 2. Use communicate() with timeout. > => This works not at all since when the timeout occurs an exception is thrown and communicate returns at all. > > 3. Use threading instead > => For being that simple and universal like subprocess you will more or less reimplement subprocess with threading, like its done in subprocess.py. Just for a debug output the effort is much to high. > > ####################################################### > Do you have further ideas for implementing such a behavior? > Do you think that a feature request should be done of I'm omitting something obvious? I'm not sure if this exactly fits your situation, but if you use subprocess with pipes, you can often get a deadlock because the stdout (or stderr, I suppose) pipe has a small capacity and fills up quickly (at least on Windows), then it blocks until it is emptied by a read. But if you aren't polling, you don't know there is something to read so the pipe never gets emptied. And if you don't read it before the pipe has filled up, you may lose data. I solved that by running communicate() on a separate thread. Let the communicate block the thread until the process has completed, then have the thread send the result back to the main program. Of course, this won't work if your process doesn't end since you won't get results until the process ends. From nospam at please.ty Tue May 9 17:22:34 2023 From: nospam at please.ty (jak) Date: Tue, 9 May 2023 23:22:34 +0200 Subject: Do subprocess.PIPE and subprocess.STDOUT sametime In-Reply-To: <40d57d83-c868-4851-a01a-c5608f4924b1n@googlegroups.com> References: <40d57d83-c868-4851-a01a-c5608f4924b1n@googlegroups.com> Message-ID: Horst Koiner ha scritto: > Hi @all, > i'm running a program which is still in development with subprocess.run (Python version 3.10), further i need to capture the output of the program in a python variable. The program itself runs about 2 minutes, but it can also freeze in case of new bugs. > > For production i run the program with stdout=subprocess.PIPE and i can fetch than the output later. For just testing if the program works, i run with stdout=subprocess.STDOUT and I see all program output on the console, but my program afterwards crashes since there is nothing captured in the python variable. So I think I need to have the functionality of subprocess.PIPE and subprcess.STDOUT sametime. > > What I tried until now: > 1. Poll the the output and use Popen instead: > > # Start the subprocess > process = subprocess.Popen(['./test.sh'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) > > captured_output = b'' > process_running = True > while process_running: > process_running = (process.poll() is not None) > for pipe in [ process.stdout, process.stderr ]: > while line := pipe.readline(): > print(line) > captured_output += line > > print(captured_output) > return_code = process.returncode > > => But this is discouraged by the python doc, since it says that polling this way is prone to deadlocks. Instead it proposes the use of the communicate() function. > > 2. Use communicate() with timeout. > => This works not at all since when the timeout occurs an exception is thrown and communicate returns at all. > > 3. Use threading instead > => For being that simple and universal like subprocess you will more or less reimplement subprocess with threading, like its done in subprocess.py. Just for a debug output the effort is much to high. > > ####################################################### > Do you have further ideas for implementing such a behavior? > Do you think that a feature request should be done of I'm omitting something obvious? > > Thanks you in advance for your suggestions, > Horst. > I agree with @'thomas Passin' but I solved in a different way, I made the Readline() not blocking. even if I believe his idea better than mine: os.set_blocking(process.stdout.fileno(), False) os.set_blocking(process.stderr.fileno(), False) From hjp-python at hjp.at Tue May 9 18:27:20 2023 From: hjp-python at hjp.at (Peter J. Holzer) Date: Wed, 10 May 2023 00:27:20 +0200 Subject: Problem with accented characters in mailbox.Maildir() In-Reply-To: References: <9jrhij-o0st1.ln1@esprimo.zbmc.eu> <20230508183618.iy3r67ifxshhe5kx@hjp.at> Message-ID: <20230509222720.oax4zh3tz4sgk7br@hjp.at> On 2023-05-08 23:02:18 +0200, jak wrote: > Peter J. Holzer ha scritto: > > On 2023-05-06 16:27:04 +0200, jak wrote: > > > Chris Green ha scritto: > > > > Chris Green wrote: > > > > > A bit more information, msg.get("subject", "unknown") does return a > > > > > string, as follows:- > > > > > > > > > > Subject: =?utf-8?Q?aka_Marne_=C3=A0_la_Sa=C3=B4ne_(Waterways_Continental_Europe)?= > > [...] > > > > ... and of course I now see the issue! The Subject: with utf-8 > > > > characters in it gets spaces changed to underscores. So searching for > > > > '(Waterways Continental Europe)' fails. > > > > > > > > I'll either need to test for both versions of the string or I'll need > > > > to change underscores to spaces in the Subject: returned by msg.get(). [...] > > > > > > subj = email.header.decode_header(raw_subj)[0] > > > > > > subj[0].decode(subj[1]) [...] > > email.header.decode_header returns a *list* of chunks and you have to > > process and concatenate all of them. > > > > Here is a snippet from a mail to html converter I wrote a few years ago: > > > > def decode_rfc2047(s): > > if s is None: > > return None > > r = "" > > for chunk in email.header.decode_header(s): [...] > > r += chunk[0].decode(chunk[1]) [...] > > return r [...] > > > > I do have to say that Python is extraordinarily clumsy in this regard. > > Thanks for the reply. In fact, I gave that answer because I did > not understand what the OP wanted to achieve. In addition, the > OP opened a second thread on the similar topic in which I gave a > more correct answer (subject: "What do these '=?utf-8?' sequences > mean in python?", date: "Sat, 6 May 2023 14:50:40 UTC"). Right. I saw that after writing my reply. I should have read all messages, not just that thread before replying. > the OP, I discovered that the MAME is not the only format used > to compose the subject. Not sure what "MAME" is. If it's a typo for MIME, then the base64 variant of RFC 2047 is just as much a part of it as the quoted-printable variant. > This made me think that a library could not delegate to the programmer > the burden of managing all these exceptions, email.header.decode_header handles both variants, but it produces bytes sequences which still have to be decoded to get a Python string. > then I have further investigated to discover that the library also > provides the conversion function beyond that of coding and this makes > our labors vain: > > ---------- > from email.header import decode_header, make_header > > subject = make_header(decode_header( raw_subject ))) > ---------- Yup. I somehow missed that. That's a lot more convenient than calling decode in a loop (or generator expression). Depending on what you want to do with the subject you may have wrap that in a call to str(), but it's still a one-liner. 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 eryksun at gmail.com Tue May 9 19:17:13 2023 From: eryksun at gmail.com (Eryk Sun) Date: Tue, 9 May 2023 18:17:13 -0500 Subject: Do subprocess.PIPE and subprocess.STDOUT sametime In-Reply-To: References: <40d57d83-c868-4851-a01a-c5608f4924b1n@googlegroups.com> Message-ID: On 5/9/23, Thomas Passin wrote: > > I'm not sure if this exactly fits your situation, but if you use > subprocess with pipes, you can often get a deadlock because the stdout > (or stderr, I suppose) pipe has a small capacity and fills up quickly > (at least on Windows), The pipe size is relatively small on Windows only because subprocess.Popen uses the default pipe size when it calls WinAPI CreatePipe(). The default size is 4 KiB, which actually should be big enough for most cases. If some other pipe size is passed, the value is "advisory", meaning that it has to be within the allowed range (but there's no practical limit on the size) and that it gets rounded up to an allocation boundary (e.g. a multiple of the system's virtual-memory page size). For example, here's a 256 MiB pipe: >>> hr, hw = _winapi.CreatePipe(None, 256*1024*1024) >>> _winapi.WriteFile(hw, b'a' * (256*1024*1024)) (268435456, 0) >>> data = _winapi.ReadFile(hr, 256*1024*1024)[0] >>> len(data) == 256*1024*1024 True > then it blocks until it is emptied by a read. > But if you aren't polling, you don't know there is something to read so > the pipe never gets emptied. And if you don't read it before the pipe > has filled up, you may lose data. If there's just one pipe, then there's no potential for deadlock, and no potential to lose data. If there's a timeout, however, then communicate() still has to use I/O polling or a thread to avoid blocking indefinitely in order to honor the timeout. Note that there's a bug in subprocess on Windows. Popen._communicate() should create a new thread for each pipe. However, it actually calls stdin.write() on the current thread, which could block and ignore the specified timeout. For example, in the following case the timeout of 5 seconds is ignored: >>> cmd = 'python -c "import time; time.sleep(20)"' >>> t0 = time.time(); p = subprocess.Popen(cmd, stdin=subprocess.PIPE) >>> r = p.communicate(b'a'*4097, timeout=5); t1 = time.time() - t0 >>> t1 20.2162926197052 There's a potential for deadlock when two or more pipes are accessed synchronously by two threads (e.g. one thread in each process). For example, reading from one of the pipes blocks one of the threads because the pipe is empty, while at the same time writing to the other pipe blocks the other thread because the pipe is full. However, there will be no deadlock if at least one of the threads always polls the pipes to ensure that they're ready (i.e. data is available to be read, or at least PIPE_BUF bytes can be written without blocking), which is how communicate() is implemented on POSIX. Alternatively, one of the processes can use a separate thread for each pipe, which is how communicate() is implemented on Windows. Note that there are problems with the naive implementation of the reader threads on Windows, in particular if a pipe handle leaks to descendants of the child process, which prevents the pipe from closing. A better implementation on Windows would use named pipes opened in asynchronous mode on the parent side and synchronous mode on the child side. Just implement a loop that handles I/O completion using events, APCs, or an I/O completion port. From jondra140 at gmail.com Wed May 10 10:19:54 2023 From: jondra140 at gmail.com (=?UTF-8?B?T25kxZllaiBKxa9u?=) Date: Wed, 10 May 2023 16:19:54 +0200 Subject: Black boxes Message-ID: Good day. After installing the Python program from your site and restarting the computer as requested by the program, problems occurred. Programs like Word are all in black. In addition, a black color appears in the file explorer which sometimes completely covers everything (the black color). This problem also appears everywhere in the "boxes where text is entered" throughout the computer. I tried uninstalling and reinstalling the program but the problem remained. I also tried to repair the program via the button in the program. I didn't get to the modifications part of the program because when I clicked on black color appeared. Python version: Python 3.11.3 (64-bit) Setup The computer I use: ASUS Vivobook Operating System: Windows 11 Home Edition Version 22H2 Operating system build 22621.1555 Thank you in advance for your reply Ond?ej From ikorot01 at gmail.com Wed May 10 11:39:54 2023 From: ikorot01 at gmail.com (Igor Korot) Date: Wed, 10 May 2023 10:39:54 -0500 Subject: Black boxes In-Reply-To: References: Message-ID: Hi, On Wed, May 10, 2023 at 10:33?AM Ond?ej J?n wrote: > > Good day. > > After installing the Python program from your site and restarting the > computer as requested by the program, problems occurred. Programs like Word > are all in black. In addition, a black color appears in the file explorer > which sometimes completely covers everything (the black color). This > problem also appears everywhere in the "boxes where text is entered" > throughout the computer. I tried uninstalling and reinstalling the program > but the problem remained. I also tried to repair the program via the button > in the program. I didn't get to the modifications part of the program > because when I clicked on black color appeared. Was there any updates installed at the time of python installation? Thank you. > > Python version: Python 3.11.3 (64-bit) Setup > > The computer I use: ASUS Vivobook > > Operating System: Windows 11 Home Edition > > Version 22H2 > > Operating system build 22621.1555 > > Thank you in advance for your reply > > Ond?ej > -- > https://mail.python.org/mailman/listinfo/python-list From mats at wichmann.us Wed May 10 14:48:50 2023 From: mats at wichmann.us (Mats Wichmann) Date: Wed, 10 May 2023 12:48:50 -0600 Subject: Black boxes In-Reply-To: References: Message-ID: On 5/10/23 08:19, Ond?ej J?n wrote: > Good day. > > After installing the Python program from your site and restarting the > computer as requested by the program, problems occurred. That's rather suspicious, because the python installer doesn't do that. That's only needed if you replace files in use by the running system, and a fresh install of Python wouldn't be "replacing" anything, now would it? What exactly did you install? From dieter at handshake.de Wed May 10 14:51:02 2023 From: dieter at handshake.de (Dieter Maurer) Date: Wed, 10 May 2023 20:51:02 +0200 Subject: Do subprocess.PIPE and subprocess.STDOUT sametime In-Reply-To: <40d57d83-c868-4851-a01a-c5608f4924b1n@googlegroups.com> References: <40d57d83-c868-4851-a01a-c5608f4924b1n@googlegroups.com> Message-ID: <25691.59286.327279.754535@ixdm.fritz.box> Horst Koiner wrote at 2023-5-9 11:13 -0700: > ... >For production i run the program with stdout=subprocess.PIPE and i can fetch than the output later. For just testing if the program works, i run with stdout=subprocess.STDOUT and I see all program output on the console, but my program afterwards crashes since there is nothing captured in the python variable. So I think I need to have the functionality of subprocess.PIPE and subprcess.STDOUT sametime. You might want to implement the functionality of the *nix programm `tee` in Python. `tee` reads from one file and writes the data to several files, i.e. it multiplexes one input file to several output files. Pyhton's `tee` would likely be implemented by a separate thread. For your case, the input file could be the subprocess's pipe and the output files `sys.stdout` and a pipe created by your own used by your application in place of the subprocess's pipe. From mats at wichmann.us Wed May 10 16:20:29 2023 From: mats at wichmann.us (Mats Wichmann) Date: Wed, 10 May 2023 14:20:29 -0600 Subject: Do subprocess.PIPE and subprocess.STDOUT sametime In-Reply-To: <25691.59286.327279.754535@ixdm.fritz.box> References: <40d57d83-c868-4851-a01a-c5608f4924b1n@googlegroups.com> <25691.59286.327279.754535@ixdm.fritz.box> Message-ID: On 5/10/23 12:51, Dieter Maurer wrote: > Horst Koiner wrote at 2023-5-9 11:13 -0700: >> ... >> For production i run the program with stdout=subprocess.PIPE and i can fetch than the output later. For just testing if the program works, i run with stdout=subprocess.STDOUT and I see all program output on the console, but my program afterwards crashes since there is nothing captured in the python variable. So I think I need to have the functionality of subprocess.PIPE and subprcess.STDOUT sametime. > > You might want to implement the functionality of the *nix programm > `tee` in Python. > `tee` reads from one file and writes the data to several files, > i.e. it multiplexes one input file to several output files. > > Pyhton's `tee` would likely be implemented by a separate thread. > > For your case, the input file could be the subprocess's pipe > and the output files `sys.stdout` and a pipe created by your own > used by your application in place of the subprocess's pipe. should you choose to go this route, there are multiple efforts floating around on the internet, worth a look. Don't know which are good and which aren't. Went looking once to see if there was something to replace a homegrown function that wasn't reliable - ended up solving that particular problem a different way so didn't use any of the tees. From jqian at tibco.com Thu May 11 10:59:01 2023 From: jqian at tibco.com (Jason Qian) Date: Thu, 11 May 2023 10:59:01 -0400 Subject: Help on ctypes.POINTER for Python array Message-ID: Hi, Need some help, in the Python, I have a array of string var_array=["Opt1=DG","Opt1=DG2"] I need to call c library and pass var_array as parameter In the argtypes, how do I set up ctypes.POINTER(???) for var_array? func.argtypes=[ctypes.c_void_p,ctypes.c_int, ctypes.POINTER(????)] In the c code: int func (void* obj, int index, char** opt) Thanks Jason From jschwar at sbcglobal.net Thu May 11 11:15:47 2023 From: jschwar at sbcglobal.net (Jim Schwartz) Date: Thu, 11 May 2023 10:15:47 -0500 Subject: Help on ctypes.POINTER for Python array In-Reply-To: References: Message-ID: <3CAFED63-B44E-4E1C-9E15-8043A66AE1AA@sbcglobal.net> I?m not sure this is the shortest method, but you could set up two python scripts to do the same thing and convert them to c using cython. I wouldn?t be able to read the c scripts, but maybe you could. Maybe someone else has a more direct answer. Sent from my iPhone > On May 11, 2023, at 10:00 AM, Jason Qian via Python-list wrote: > > ?Hi, > > Need some help, > > in the Python, I have a array of string > > var_array=["Opt1=DG","Opt1=DG2"] > > I need to call c library and pass var_array as parameter > > In the argtypes, how do I set up ctypes.POINTER(???) for var_array? > > func.argtypes=[ctypes.c_void_p,ctypes.c_int, ctypes.POINTER(????)] > > In the c code: > > int func (void* obj, int index, char** opt) > > Thanks > Jason > -- > https://mail.python.org/mailman/listinfo/python-list From eryksun at gmail.com Thu May 11 13:47:50 2023 From: eryksun at gmail.com (Eryk Sun) Date: Thu, 11 May 2023 12:47:50 -0500 Subject: Help on ctypes.POINTER for Python array In-Reply-To: References: Message-ID: On 5/11/23, Jason Qian via Python-list wrote: > > in the Python, I have a array of string > var_array=["Opt1=DG","Opt1=DG2"] > I need to call c library and pass var_array as parameter > In the argtypes, how do I set up ctypes.POINTER(???) for var_array? > > func.argtypes=[ctypes.c_void_p,ctypes.c_int, ctypes.POINTER(????)] > > In the c code: > int func (void* obj, int index, char** opt) The argument type is ctypes.POINTER(ctypes.c_char_p), but that's not sufficient. It doesn't implement converting a list of str objects into an array of c_char_p pointers that reference byte strings. You could write a wrapper function that implements the conversion before calling func(), or you could set the argument type to a custom subclass of ctypes.POINTER(ctypes.c_char_p) that implements the conversion via the from_param() class method. https://docs.python.org/3/library/ctypes.html#ctypes._CData.from_param Here's an example of the latter. C library: #include int func(void *obj, int index, char **opt) { int length; for (length=0; opt[length]; length++); if (index < 0 || index >= length) { return -1; } return printf("%s\n", opt[index]); } Python: import os import ctypes lib = ctypes.CDLL('./lib.so') BaseOptions = ctypes.POINTER(ctypes.c_char_p) class Options(BaseOptions): @classmethod def from_param(cls, param): if isinstance(param, list): new_param = (ctypes.c_char_p * (len(param) + 1))() for i, p in enumerate(param): new_param[i] = os.fsencode(p) param = new_param return BaseOptions.from_param(param) lib.func.argtypes = (ctypes.c_void_p, ctypes.c_int, Options) demo: >>> opts = ['Opt1=DG', 'Opt1=DG2'] >>> lib.func(None, 0, opts) Opt1=DG 8 >>> lib.func(None, 1, opts) Opt1=DG2 9 From jqian at tibco.com Thu May 11 13:58:33 2023 From: jqian at tibco.com (Jason Qian) Date: Thu, 11 May 2023 13:58:33 -0400 Subject: Help on ctypes.POINTER for Python array In-Reply-To: References: Message-ID: Awesome, thanks! On Thu, May 11, 2023 at 1:47?PM Eryk Sun wrote: > On 5/11/23, Jason Qian via Python-list wrote: > > > > in the Python, I have a array of string > > var_array=["Opt1=DG","Opt1=DG2"] > > I need to call c library and pass var_array as parameter > > In the argtypes, how do I set up ctypes.POINTER(???) for var_array? > > > > func.argtypes=[ctypes.c_void_p,ctypes.c_int, ctypes.POINTER(????)] > > > > In the c code: > > int func (void* obj, int index, char** opt) > > The argument type is ctypes.POINTER(ctypes.c_char_p), but that's not > sufficient. It doesn't implement converting a list of str objects into > an array of c_char_p pointers that reference byte strings. You could > write a wrapper function that implements the conversion before calling > func(), or you could set the argument type to a custom subclass of > ctypes.POINTER(ctypes.c_char_p) that implements the conversion via the > from_param() class method. > > https://docs.python.org/3/library/ctypes.html#ctypes._CData.from_param > > Here's an example of the latter. > > C library: > > #include > > int > func(void *obj, int index, char **opt) > { > int length; > for (length=0; opt[length]; length++); > if (index < 0 || index >= length) { > return -1; > } > return printf("%s\n", opt[index]); > } > > > Python: > > import os > import ctypes > > lib = ctypes.CDLL('./lib.so') > BaseOptions = ctypes.POINTER(ctypes.c_char_p) > > class Options(BaseOptions): > @classmethod > def from_param(cls, param): > if isinstance(param, list): > new_param = (ctypes.c_char_p * (len(param) + 1))() > for i, p in enumerate(param): > new_param[i] = os.fsencode(p) > param = new_param > return BaseOptions.from_param(param) > > lib.func.argtypes = (ctypes.c_void_p, ctypes.c_int, Options) > > > demo: > > >>> opts = ['Opt1=DG', 'Opt1=DG2'] > >>> lib.func(None, 0, opts) > Opt1=DG > 8 > >>> lib.func(None, 1, opts) > Opt1=DG2 > 9 > From davidlerik8 at gmail.com Fri May 12 02:42:15 2023 From: davidlerik8 at gmail.com (David John) Date: Fri, 12 May 2023 09:42:15 +0300 Subject: pip module not found Message-ID: Hi, I recently have been experiencing issues with the pip installation module. I have python version 3.11 installed. I've checked the directory installed in the systems variables window and nothing is amiss. Kindly assist. Regards, David From mats at wichmann.us Fri May 12 11:06:59 2023 From: mats at wichmann.us (Mats Wichmann) Date: Fri, 12 May 2023 09:06:59 -0600 Subject: pip module not found In-Reply-To: References: Message-ID: On 5/12/23 00:42, David John wrote: > Hi, > I recently have been experiencing issues with the pip installation module. How? Please be explicit or nobody can answer your question. From list1 at tompassin.net Fri May 12 12:50:14 2023 From: list1 at tompassin.net (Thomas Passin) Date: Fri, 12 May 2023 12:50:14 -0400 Subject: pip module not found In-Reply-To: References: Message-ID: On 5/12/2023 11:18 AM, Thomas Passin wrote: > On 5/12/2023 2:42 AM, David John wrote: >> Hi, >> I recently have been experiencing issues with the pip installation >> module. >> I have python version 3.11 installed. I've checked the directory >> installed >> in the systems variables window and nothing is amiss. Kindly assist. > > It would be useful if you told us what operating system you are using > and how you installed Python. > > Many if not most Linux distributions do not include pip by default. > Usually the package manager as a version to install.? On systems based > on Debian, you can install pip with: > > sudo apt install python3-pip > > On others, you will have to look around in the package manager or search > on line. > > As a last resort, if you cannot find an OS package manager way to > install pip, you find out how from here: > > https://pip.pypa.io/en/stable/installation/ > > As the link says, you can run from a command line: > > -m ensurepip --upgrade > > NOTE: instead of , use the command that launches the right > version of python on your system? On Windows, this is usually py.? On > Linux, it is usually python3. On Linux, if you want tkinter, you may have to install it with the package manager too. On Debian-related systems: sudo apt-get install python3-tk For the Yum package manager: yum install tkinter You may also need to install ImageTk: sudo apt-get install python3-pil.imagetk (Debian-based) On Centos/Red Hat derived systems, you will also need to install python3-pillow python3-pillow-tk From barry at barrys-emacs.org Fri May 12 13:45:21 2023 From: barry at barrys-emacs.org (Barry) Date: Fri, 12 May 2023 18:45:21 +0100 Subject: pip module not found In-Reply-To: References: Message-ID: <9E9BAE1F-9EBF-4CBC-9FD5-F1CFB79D964E@barrys-emacs.org> > On 12 May 2023, at 18:31, Thomas Passin wrote: > > ?On 5/12/2023 11:18 AM, Thomas Passin wrote: >>> On 5/12/2023 2:42 AM, David John wrote: >>> Hi, >>> I recently have been experiencing issues with the pip installation module. >>> I have python version 3.11 installed. I've checked the directory installed >>> in the systems variables window and nothing is amiss. Kindly assist. >> It would be useful if you told us what operating system you are using and how you installed Python. >> Many if not most Linux distributions do not include pip by default. Usually the package manager as a version to install. On systems based on Debian, you can install pip with: >> sudo apt install python3-pip >> On others, you will have to look around in the package manager or search on line. >> As a last resort, if you cannot find an OS package manager way to install pip, you find out how from here: >> https://pip.pypa.io/en/stable/installation/ >> As the link says, you can run from a command line: >> -m ensurepip --upgrade >> NOTE: instead of , use the command that launches the right version of python on your system On Windows, this is usually py. On Linux, it is usually python3. > > On Linux, if you want tkinter, you may have to install it with the package manager too. On Debian-related systems: > > sudo apt-get install python3-tk > > For the Yum package manager: > > yum install tkinter > > You may also need to install ImageTk: > > sudo apt-get install python3-pil.imagetk (Debian-based) > > On Centos/Red Hat derived systems, you will also need to install > > python3-pillow > python3-pillow-tk > PIP not PIL is the topic right? We still need OP to tell us which OS and where python came from. Barry > > > -- > https://mail.python.org/mailman/listinfo/python-list From list1 at tompassin.net Fri May 12 14:07:30 2023 From: list1 at tompassin.net (Thomas Passin) Date: Fri, 12 May 2023 14:07:30 -0400 Subject: pip module not found In-Reply-To: <9E9BAE1F-9EBF-4CBC-9FD5-F1CFB79D964E@barrys-emacs.org> References: <9E9BAE1F-9EBF-4CBC-9FD5-F1CFB79D964E@barrys-emacs.org> Message-ID: On 5/12/2023 1:45 PM, Barry wrote: > > >> On 12 May 2023, at 18:31, Thomas Passin wrote: >> >> ?On 5/12/2023 11:18 AM, Thomas Passin wrote: >>>> On 5/12/2023 2:42 AM, David John wrote: >>>> Hi, >>>> I recently have been experiencing issues with the pip installation module. >>>> I have python version 3.11 installed. I've checked the directory installed >>>> in the systems variables window and nothing is amiss. Kindly assist. >>> It would be useful if you told us what operating system you are using and how you installed Python. >>> Many if not most Linux distributions do not include pip by default. Usually the package manager as a version to install. On systems based on Debian, you can install pip with: >>> sudo apt install python3-pip >>> On others, you will have to look around in the package manager or search on line. >>> As a last resort, if you cannot find an OS package manager way to install pip, you find out how from here: >>> https://pip.pypa.io/en/stable/installation/ >>> As the link says, you can run from a command line: >>> -m ensurepip --upgrade >>> NOTE: instead of , use the command that launches the right version of python on your system On Windows, this is usually py. On Linux, it is usually python3. >> >> On Linux, if you want tkinter, you may have to install it with the package manager too. On Debian-related systems: >> >> sudo apt-get install python3-tk >> >> For the Yum package manager: >> >> yum install tkinter >> >> You may also need to install ImageTk: >> >> sudo apt-get install python3-pil.imagetk (Debian-based) >> >> On Centos/Red Hat derived systems, you will also need to install >> >> python3-pillow >> python3-pillow-tk >> > > PIP not PIL is the topic right? > > We still need OP to tell us which OS and where python came from. > > Barry Sure, Pip is the topic. But on Linux, once you have it installed, Tk may not be far behind, so I thought I'd mention the info since I've been bitten by it myself, and it's not obvious what to do. By throwing out a number of common possibilities I was hoping to cover the OP's situation - and help others who didn't write in - I've been there. And yes, of course it would be better to have the OP's detailed information. Let's hope that if the OP does succeed we will get to know of it. From list1 at tompassin.net Fri May 12 11:18:51 2023 From: list1 at tompassin.net (Thomas Passin) Date: Fri, 12 May 2023 11:18:51 -0400 Subject: pip module not found In-Reply-To: References: Message-ID: On 5/12/2023 2:42 AM, David John wrote: > Hi, > I recently have been experiencing issues with the pip installation module. > I have python version 3.11 installed. I've checked the directory installed > in the systems variables window and nothing is amiss. Kindly assist. It would be useful if you told us what operating system you are using and how you installed Python. Many if not most Linux distributions do not include pip by default. Usually the package manager as a version to install. On systems based on Debian, you can install pip with: sudo apt install python3-pip On others, you will have to look around in the package manager or search on line. As a last resort, if you cannot find an OS package manager way to install pip, you find out how from here: https://pip.pypa.io/en/stable/installation/ As the link says, you can run from a command line: -m ensurepip --upgrade NOTE: instead of , use the command that launches the right version of python on your system On Windows, this is usually py. On Linux, it is usually python3. From koinerhorst6 at gmail.com Fri May 12 12:55:17 2023 From: koinerhorst6 at gmail.com (Horst Koiner) Date: Fri, 12 May 2023 09:55:17 -0700 (PDT) Subject: Do subprocess.PIPE and subprocess.STDOUT sametime In-Reply-To: References: <9da63d82-55d2-bb0c-33d2-10b5d28a8dc8@wichmann.us> <40d57d83-c868-4851-a01a-c5608f4924b1n@googlegroups.com> Message-ID: <73e64816-7024-40e0-8b72-d3fcae7db945n@googlegroups.com> Using asyncio for this is a good possibility I was not aware of. My best try with asyncio was: import asyncio async def run_command(): # Create subprocess process = await asyncio.create_subprocess_exec( './test.sh', stdout=asyncio.subprocess.PIPE, # Redirect stdout to a pipe stderr=asyncio.subprocess.PIPE # Redirect stderr to a pipe ) # Read stdout and stderr asynchronously captured_output = b'' async for line in process.stdout: print(line.decode().strip()) captured_output += line async for line in process.stderr: print(line.decode().strip()) captured_output += line await process.wait() print(captured_output) # Run the asyncio event loop asyncio.run(run_command()) ######################################## This fulfills all my requirements. A nice to have would that the captured_output has not to be constructed with += 's but with a final seek(0) and read() of process.stdout. But I didn't find anything how to rewind the stream, that i can read the whole output again. Another question is, if this solution is deadlock proof. Thank you all for the already very valuable input! Greetings, Horst From barry at barrys-emacs.org Fri May 12 17:28:16 2023 From: barry at barrys-emacs.org (Barry) Date: Fri, 12 May 2023 22:28:16 +0100 Subject: pip module not found In-Reply-To: References: Message-ID: > On 12 May 2023, at 21:59, Thomas Passin wrote: > > ?On 5/12/2023 2:42 AM, David John wrote: >> Hi, >> I recently have been experiencing issues with the pip installation module. >> I have python version 3.11 installed. I've checked the directory installed >> in the systems variables window and nothing is amiss. Kindly assist. > > It would be useful if you told us what operating system you are using and how you installed Python. > > Many if not most Linux distributions do not include pip by default. Usually the package manager as a version to install. From what i see the fedora/redhat/centos world includes the batteries. The debian/ubuntu world take batteries out. > On systems based on Debian, you can install pip with: > > sudo apt install python3-pip > > On others, you will have to look around in the package manager or search on line. > > As a last resort, if you cannot find an OS package manager way to install pip, you find out how from here: > > https://pip.pypa.io/en/stable/installation/ > > As the link says, you can run from a command line: > > -m ensurepip --upgrade > > NOTE: instead of , use the command that launches the right version of python on your system On Windows, this is usually py. On Linux, it is usually python3. > > > -- > https://mail.python.org/mailman/listinfo/python-list > From rosuav at gmail.com Fri May 12 17:41:31 2023 From: rosuav at gmail.com (Chris Angelico) Date: Sat, 13 May 2023 07:41:31 +1000 Subject: Do subprocess.PIPE and subprocess.STDOUT sametime In-Reply-To: <73e64816-7024-40e0-8b72-d3fcae7db945n@googlegroups.com> References: <9da63d82-55d2-bb0c-33d2-10b5d28a8dc8@wichmann.us> <40d57d83-c868-4851-a01a-c5608f4924b1n@googlegroups.com> <73e64816-7024-40e0-8b72-d3fcae7db945n@googlegroups.com> Message-ID: On Sat, 13 May 2023 at 07:21, Horst Koiner wrote: > > Using asyncio for this is a good possibility I was not aware of. > > My best try with asyncio was: > import asyncio > > async def run_command(): > # Create subprocess > process = await asyncio.create_subprocess_exec( > './test.sh', > stdout=asyncio.subprocess.PIPE, # Redirect stdout to a pipe > stderr=asyncio.subprocess.PIPE # Redirect stderr to a pipe > ) > > # Read stdout and stderr asynchronously > captured_output = b'' > async for line in process.stdout: > print(line.decode().strip()) > captured_output += line > async for line in process.stderr: > print(line.decode().strip()) > captured_output += line > > await process.wait() > print(captured_output) > > > # Run the asyncio event loop > asyncio.run(run_command()) > ######################################## > > This fulfills all my requirements. A nice to have would that the captured_output has not to be constructed with += 's but with a final seek(0) and read() of process.stdout. But I didn't find anything how to rewind the stream, that i can read the whole output again. > Another question is, if this solution is deadlock proof. > No it's not, but the best part is, it's really close to! Asynchronous I/O is perfect for this: you need to wait for any of three events (data on stdout, data on stderr, or process termination). So here it is as three tasks: captured_output = b"" async def collect_output(stream): global captured_output async for line in stream: print(line.decode().strip()) captured_output += line (You can play around with other ways of scoping this, I'm just using a global for simplicity) Inside run_command, you can then spawn three independent tasks and await them simultaneously. Once all three finish, you have your captured output, and the process will have terminated. This would then be guaranteed deadlock-proof (and, if you needed to feed data on stdin, you could do that with a fourth task and it'd still be deadlock-proof, even if it's more than one pipe buffer of input), since all the pipes are being managed concurrently. Even cooler? You can scale this up to multiple processes by calling run_command more than once as separate tasks! ChrisA From diegofpsouza at gmail.com Fri May 12 23:00:14 2023 From: diegofpsouza at gmail.com (Diego Souza) Date: Sat, 13 May 2023 00:00:14 -0300 Subject: Multithreading? How? In-Reply-To: References: Message-ID: Hi there, I hope this e-mail is still on time for you. I have implemented this architecture a few times, and they all work fine nowadays. However, your question made me review it and create a small gist. I suggest you create a thread for every output and input connection. This makes it easier to focus on reading or writing inside a given object. For example, in your project, I would separate it into IotReader, IotWriter, MqttReader, and MqttWriter. Another thing I do to avoid manipulating multiple locks, semaphores, and so on is to create a central event loop. For every event that comes from IotReader or MqttReader, I would pack it into an event and send it to a central thread. This is the main gateway thread, and I would call it Gateway. I don't know if you have ever programmed in Android. But the Android framework uses a similar approach to processing data. Whenever you need to process something, you start a new 'Thread', and when you need to present the result in the interface you dispatch events until the main thread is notified and updates the corresponding Views. The point here is: never do any extensive processing in the main thread as it is going delay. You will probably not do it now, but if you ever need it, make a pool of workers to process this and keep the Gateway free. Replace the Threads with multiprocessing.Process, as well, as Python lacks true multithreading. Regarding thread/process communication, I like to implement this using Queues. The Gateway class would have a main_queue to receive events from IotReader and MqttReader. IotWriter and MqttWriter have a particular queue as well. Whenever the Gateway needs to send something to either of them, it just needs to reference their respective queues, which I wrap inside a method, for simplicity. Another benefit of this architecture is the ability to scale to more connections easily. In the past, I have used this strategy to schedule tasks for up to about 20 devices (each with an input and output thread). I believe it could go higher, but I haven't needed to. There are fully distributed architectures more suitable for hundreds and thousands of connections, but this is likely not what you need now. The following is a possible implementation for the IotReader. You need to replace the AnySerialReader class and its read method with the initialization of your own Bus wrapper. The read method must have a timeout parameter if you want to cancel the operation properly. The terminate method is used to terminate the program properly. *class IotReader(Thread): def __init__(self, queue_master, name='IotReader'): super().__init__() self.queue_master = queue_master self.queue = Queue() self.done = False self.name = name self.start() def terminate(self): self.done = True def run(self): log.info (f"Starting thread for {self.name }") serial_reader = AnySerialReader('Serial' + self.name ) log.info (f"Serial reader for {self.name } initialized") while not self.done: try: data = serial_reader.read(timeout=1) if data is None: continue self.queue_master.put(('on_iot_event', data)) except: traceback.print_exc(file=sys.stdout) log.warning("Terminating IotReader") serial_reader.terminate()* The following is a possible implementation for IotWriter. It adds a method named send that adds new tasks to the queue. The main loop, running inside the thread, waits for these events and calls write in AnySerialWriter. This may be a slow operation, the connection may be down, and we need to reconnect, etc. This is why we need a thread for the output message as well. *class IotWriter(Thread): def __init__(self, name='IotWriter'): super().__init__() self.queue = Queue() self.done = False self.name = name self.start() def terminate(self): self.done = True self.queue.put( ('terminate', None) ) def send(self, data): self.queue.put( ('write_message', data) ) def run(self): log.info (f"Starting thread for {self.name }") serial_writer = AnySerialWriter('Serial' + self.name ) log.info (f"Serial writer for {self.name } initialized") while not self.done: try: action, data = self.queue.get() if action == 'terminate': break elif action == 'write_message': serial_writer.write(data) else: log.error(f'Unknown action for IotWriter - action={action}, data={data}') except: traceback.print_exc(file=sys.stdout) log.warning("Terminating IotWriter") serial_writer.terminate()* I do not include the source for a MqttReceiver and MqttWriter as they are very similar, in structure, to IotWriter and MqttWriter. The code below is for the Gateway class. It initializes all readers and writers. Following that, it will wait for input messages and process them adequately. You could add as many events as you need. I used two to illustrate. *class Gateway(Thread): def __init__(self): super().__init__() self.queue_master = Queue() self.done = False self.start() def run(self): log.info ("Starting Gateway") while not self.done: try: self.iot_reader = IotReader(self.queue_master) self.iot_writer = IotWriter() self.mqtt_reader = MqttReader(self.queue_master) self.mqtt_writer = MqttWriter() log.info (f"Starting {self.__class__.__name__}") while not self.done: try: action, data = self.queue_master.get() if action in 'on_mqtt_event': self.on_mqtt_event(data) elif action == 'on_iot_event': self.on_iot_event(data) elif action == 'terminate': break else: log.error(f'Unknown action, action={action}, data={data}') except: log.error("Error during message parsing") traceback.print_exc(file=sys.stdout) except: log.error("Error during gateway configuration") traceback.print_exc(file=sys.stdout) self.iot_reader.terminate() self.iot_writer.terminate() self.mqtt_reader.terminate() self.mqtt_writer.terminate() self.iot_reader.join() self.iot_writer.join() self.mqtt_reader.join() self.mqtt_writer.join() log.warning('Terminating Gateway') def terminate(self): self.done = True self.queue_master.put(('terminate', None)) def on_iot_event(self, data): log.info (f'Event from iot device, forwarding to mqtt, data={data}') self.mqtt_writer.send(data) def on_mqtt_event(self, data): log.info (f'Event from iot device, forwarding to iot, data={data}') self.iot_writer.send(data)* I started the Gateway using the code below. It calls the method terminate when I press Ctrl+C. This event could also come from the MQTT server or anywhere else. *gateway = Gateway()# Your main thread is free here. You could start a webserver and display # a dashboard. Or wait, like below.try: gateway.join()except KeyboardInterrupt: log.info ("Sending terminate command...") gateway.terminate()try: gateway.join()except KeyboardInterrupt: log.info ("Killing the app...") sys.exit(0) passlog.info ("Bye!")* If you want to check the full code, a small gist in the link below: *https://gist.github.com/diegofps/87945a0c3e800c747f3af07833ff6b7e * You also mentioned discovering the device status and sending it back through MQTT. I can see two approaches to this. The first approach is to cache the status emitted from the device. This is fine if the data is small enough to keep in the gateway memory. Then, I would send it back through MQTT immediately. The second approach is to forward the request to the device. The device will later respond to your query with the original question and response. You likely need the question as you need to remember what you need to do with it now. It is stateless. You could also mix these two approaches and cache the state for a certain amount of time. After that, it would expire, and you would ask the device again. This is an overview of how I implement it nowadays. I am sure other people may have different strategies and ideas to improve it. Best, Diego On Fri, Apr 28, 2023 at 1:10?PM pozz wrote: > I need to develop a Python application that is a sort of gateway between > to networks: a "serial bus" network (think of a serial port or a USB > connection) and a MQTT connection (in my case, it's AWS IoT service). > > On the bus, a proprietary protocol is implemented. From the bus, the app > knows the status of the system (think of a simple ON/OFF status). > The user can retrieve the status of the system through MQTT: it sends a > message to read/status MQTT topic and receive back a message with the > current status on read/status/reply MQTT topic. Of course, they are just > examples. > > On the contrary, when the app detects a status change reported from the > serial bus (think of a transition from ON to OFF), it sends a MQTT message. > > I'm thinking to split the application in three classes: Bus, App and > IoT. Bus and IoT are also threads. > The thread of Bus manages the serial protocol, while the thread of IoT > manages MQTT connection with the broker (the server). > > However I don't know if it could be a good architecture. Suppone Bus > thread receives a new status from the system. In the context of > ThreadBus, the object Bus could call a method of App object: > > app.set_status(new_status_from_the_bus) > > In the App I have: > > class App(): > .. > def set_status(new_status): # Could be called from ThreadBus > if new_status != self.new_status: > self.new_status = new_status > # Do some actions on status change > > def get_status(): # Could be called from ThreadIoT > return self.status > > Of course, IoT object needs to know the current status of the system > when a message is received from MQTT. So ThreadIoT could call > app.get_status(). > > I think this architecture has some problems with race conditions or > threads synchronization. What happens if IoT calls get_status() exactly > when set_status() called by ThreadBus is executing? If status is a big > data structure, set_status() could be interrupted by get_status() that > could get a completely corrupted status, because it was only partly > updated by set_status(). > > I know I can use locks or semaphores in get_status() and set_status(), > but I don't know if this is a good approach. Consider that the system is > complex, it isn't composed by a simple single status. It has many many > parameters that are collected from the serial bus. Should I use a lock > for every [get|set]_status(), [get|set]_dimensions(), > [get|set]_battery_level(), [get|set]_mains_present(), and so on? > > > Another possibility is to use a Queue for Bus and a Queue for IoT. So > the set_status(new_status) called from Bus object will be transformed in > a put in the queue: > > app_queue.put({"type": "new_status", "data": ...}) > > However how could be transformed the get_status() from IoT? How the > return value (the current status) is real retrieved? > > class IoT(): > .. > def status_request_from_MQTT(): > app_queue.put({"type": "get_status"}) > # How to get the status to return? > return current_status > > Should the app put the status on the same queue and should IoT waits for > a new message in the Queue? > > def status_request_from_MQTT(): > app_queue.put({"type": "get_status"}) > try: > current_status = app_queue.get(timeout=10) > except Empty: > # What to do? > return current_status > > > Again another approach is to avoid multi-threading at all and create a > single "main loop" function that waits at the same time for incoming > events on the serial bus and MQTT (how?). I don't know if this could be > done in my case, because I'm using awscrt Python module and it works > through callbacks that I think is called from another thread. > > > Any suggestions on this architecture? > -- > https://mail.python.org/mailman/listinfo/python-list > -- Diego Souza Wespa Intelligent Systems Rio de Janeiro - Brasil From RealGrizzlyAdams at vivaldi.net Sat May 13 06:42:52 2023 From: RealGrizzlyAdams at vivaldi.net (Grizzy Adams) Date: Sat, 13 May 2023 11:42:52 +0100 Subject: PythonPath / sys.path Message-ID: <645F69AC.14631.33F7F4@RealGrizzlyAdams.vivaldi.net> Hi All My first post (repeated) I am having a problem with PythonPath / sys.path I have a dir where I keep all my current work, but I can't seem to add it to PythonPath / sys.path When I try to import one of my modules I see >>>import My_Working_File Traceback (most recent call last): File "", line 1, in import My_Working_File ImportError: No module named 'My_Working_File' I have tried adding my dir in registry to the existing PythonPath [HKEY_CURRENT_USER\Software\Python\PythonCore\3.4\PythonPath] @="D:\\Shades\\Tools\\Python\\Lib;D:\\Shades\\Tools\\Python\\DLLs" that did not help, I tried adding PYTHONPATH as an enviramental variable, that also had no effect (I did re-boot after these two tests) If I go to the editor window and run (F5) any of my modules then I can >>> ================================ RESTART ================================ >>> >>> import My_Working_File >>> without error I can also (from a fresh start) >>> import sys >>> sys.path.append(r'D:\Shades\Tools\Python\MyWork') >>> print(sys.path) ['', 'D:\\Shades\\Tools\\Python\\Lib\\idlelib', 'D:\\Shades\\Tools\\Python\\python34.zip', 'D:\\Shades\\Tools\\Python\\DLLs', 'D:\\Shades\\Tools\\Python\\lib', 'D:\\Shades\\Tools\\Python', 'D:\\Shades\\Tools\\Python\\lib\\site-packages', 'D:\\Shades\\Tools\\Python\\MyWork'] >>> import My_Working_File >>> I don't really want to go this route every time I start work, and more to the point I will need (to learn how) to add dir's to the path at times I did search the net for an answer but only got what I had already tried any pointers what I'm doing wrong (other than using windows '->) Grizz From barry at barrys-emacs.org Sun May 14 12:43:43 2023 From: barry at barrys-emacs.org (Barry) Date: Sun, 14 May 2023 17:43:43 +0100 Subject: PythonPath / sys.path In-Reply-To: <645F69AC.14631.33F7F4@RealGrizzlyAdams.vivaldi.net> References: <645F69AC.14631.33F7F4@RealGrizzlyAdams.vivaldi.net> Message-ID: <12B1206B-7773-4870-B3CC-93126AEEFC70@barrys-emacs.org> > On 14 May 2023, at 16:32, Grizzy Adams via Python-list wrote: > > ?Hi All > > My first post (repeated) > > I am having a problem with PythonPath / sys.path > > I have a dir where I keep all my current work, but I can't seem to add it to > PythonPath / sys.path > > When I try to import one of my modules I see > >>>> import My_Working_File > Traceback (most recent call last): > File "", line 1, in > import My_Working_File > ImportError: No module named 'My_Working_File' > > I have tried adding my dir in registry to the existing PythonPath > > [HKEY_CURRENT_USER\Software\Python\PythonCore\3.4\PythonPath] > @="D:\\Shades\\Tools\\Python\\Lib;D:\\Shades\\Tools\\Python\\DLLs" > > that did not help, > > I tried adding PYTHONPATH as an enviramental variable, that also had no effect > > (I did re-boot after these two tests) > > If I go to the editor window and run (F5) any of my modules then I can > >>>> ================================ RESTART ================================ >>>> >>>> import My_Working_File >>>> > > without error > > I can also (from a fresh start) > >>>> import sys >>>> sys.path.append(r'D:\Shades\Tools\Python\MyWork') >>>> print(sys.path) > ['', 'D:\\Shades\\Tools\\Python\\Lib\\idlelib', > 'D:\\Shades\\Tools\\Python\\python34.zip', 'D:\\Shades\\Tools\\Python\\DLLs', > 'D:\\Shades\\Tools\\Python\\lib', 'D:\\Shades\\Tools\\Python', > 'D:\\Shades\\Tools\\Python\\lib\\site-packages', > 'D:\\Shades\\Tools\\Python\\MyWork'] >>>> import My_Working_File >>>> > > I don't really want to go this route every time I start work, and more to the > point I will need (to learn how) to add dir's to the path at times > > I did search the net for an answer but only got what I had already tried > > any pointers what I'm doing wrong (other than using windows '->) I take it you have business reasons to use an obsolete version python. Where did you get your version of python from? You seem to be doing the right thing with setting an environment variable. Useless shades is an app that embeds python. Try starting cmd.exe and using the set command to liat all of the environment. Do you see your PYTHONPATH variable? Does it contain what you expect? If it does start python and check that sys.path has your folder in it. Also check what is on os.environ dirctionary. Barry > > Grizz > -- > https://mail.python.org/mailman/listinfo/python-list > From mats at wichmann.us Sun May 14 13:11:26 2023 From: mats at wichmann.us (Mats Wichmann) Date: Sun, 14 May 2023 11:11:26 -0600 Subject: PythonPath / sys.path In-Reply-To: <12B1206B-7773-4870-B3CC-93126AEEFC70@barrys-emacs.org> References: <645F69AC.14631.33F7F4@RealGrizzlyAdams.vivaldi.net> <12B1206B-7773-4870-B3CC-93126AEEFC70@barrys-emacs.org> Message-ID: On 5/14/23 10:43, Barry wrote: > I take it you have business reasons to use an obsolete version python. > Where did you get your version of python from? In fact, a *nine* year old version of Python that reached end-of-life four years ago. Just sayin' Python version shouldn't have anything to do with the sys.path, though. From RealGrizzlyAdams at vivaldi.net Sun May 14 15:00:52 2023 From: RealGrizzlyAdams at vivaldi.net (Grizzy Adams) Date: Sun, 14 May 2023 20:00:52 +0100 Subject: PythonPath / sys.path In-Reply-To: References: <645F69AC.14631.33F7F4@RealGrizzlyAdams.vivaldi.net>, <12B1206B-7773-4870-B3CC-93126AEEFC70@barrys-emacs.org>, Message-ID: <64612FE4.15459.124FD5F@RealGrizzlyAdams.vivaldi.net> Sunday, May 14, 2023 at 11:11, Mats Wichmann wrote: Re: PythonPath / sys.path (at least in part) >On 5/14/23 10:43, Barry wrote: >> I take it you have business reasons to use an obsolete version python. >> Where did you get your version of python from? >In fact, a *nine* year old version of Python that reached end-of-life >four years ago. >Just sayin' >Python version shouldn't have anything to do with the sys.path, though. I must have slept a while Python 3.4.10 (default, Jul 14 2019, 14:41:03) [MSC v.1600 32 bit (Intel)] on win32 Actually I did have 3..4.3 when I asked the question (first time) because I could only find 3.4.10 as src and did not feel I was able to compile it with any certainty ;->) I have since moved up (a little) so only ~4 years old, I then updated pip from 9.x to 19.1 reason its an old version is it's an old PC (XpPro), if I start to get passable at this I will try it on my Ubuntu box which is running 22.04 (latest LTS) and 23.04, (23.10 daily builds soon) I took a look and it seems I "may" have to play a little to get IDLE on (if it's not in the normal repo's) I seem to have managed to sort "PythonPath / sys.path" the environment variable is working, so I can now import my_work without any other hassle, which is good, now I find that some of the files which worked a treat from GUI, Editor (F5) or terminal but don't do the same once saved and imported later, I'm sure it's me, I have come from VB/VBA, Delphi and a (very) little C++, and am still working through the python tutorial, trying not to skip ahead (ok I did skip "Hello World" :->) so I may end up asking some (senior moment) newbie questions, I will try hard to work it out myself first Thanks to all who got me thus far Grizz From mats at wichmann.us Sun May 14 15:48:43 2023 From: mats at wichmann.us (Mats Wichmann) Date: Sun, 14 May 2023 13:48:43 -0600 Subject: PythonPath / sys.path In-Reply-To: <64612FE4.15459.124FD5F@RealGrizzlyAdams.vivaldi.net> References: <645F69AC.14631.33F7F4@RealGrizzlyAdams.vivaldi.net> <12B1206B-7773-4870-B3CC-93126AEEFC70@barrys-emacs.org> <64612FE4.15459.124FD5F@RealGrizzlyAdams.vivaldi.net> Message-ID: On 5/14/23 13:00, Grizzy Adams via Python-list wrote: > Sunday, May 14, 2023 at 11:11, Mats Wichmann wrote: > Re: PythonPath / sys.path (at least in part) > >> On 5/14/23 10:43, Barry wrote: > >>> I take it you have business reasons to use an obsolete version python. >>> Where did you get your version of python from? > >> In fact, a *nine* year old version of Python that reached end-of-life >> four years ago. > >> Just sayin' > >> Python version shouldn't have anything to do with the sys.path, though. > > I must have slept a while > > Python 3.4.10 (default, Jul 14 2019, 14:41:03) [MSC v.1600 32 bit (Intel)] on > win32 > > Actually I did have 3..4.3 when I asked the question (first time) because I > could only find 3.4.10 as src and did not feel I was able to compile it with > any certainty ;->) > > I have since moved up (a little) so only ~4 years old, I then updated pip from > 9.x to 19.1 > > reason its an old version is it's an old PC (XpPro), if I start to get passable yes, it's true that 3.4 was the last release supported on XP, so that's a pretty good reason (of course we can ask why still running XP, but I do understand old machines...) > at this I will try it on my Ubuntu box which is running 22.04 (latest LTS) and > 23.04, (23.10 daily builds soon) I took a look and it seems I "may" have to > play a little to get IDLE on (if it's not in the normal repo's) IDLE is still supported, you shouldn't have any trouble getting it. https://packages.ubuntu.com/lunar/idle From eryksun at gmail.com Sun May 14 18:12:52 2023 From: eryksun at gmail.com (Eryk Sun) Date: Sun, 14 May 2023 17:12:52 -0500 Subject: PythonPath / sys.path In-Reply-To: <645F69AC.14631.33F7F4@RealGrizzlyAdams.vivaldi.net> References: <645F69AC.14631.33F7F4@RealGrizzlyAdams.vivaldi.net> Message-ID: On 5/13/23, Grizzy Adams via Python-list wrote: > > I have tried adding my dir in registry to the existing PythonPath > > [HKEY_CURRENT_USER\Software\Python\PythonCore\3.4\PythonPath] > @="D:\\Shades\\Tools\\Python\\Lib;D:\\Shades\\Tools\\Python\\DLLs" > > that did not help, The default value of the above registry key is only used if Python can't calculate the default sys.path based on searching for "os.py", the landmark module in the standard library. This can happen sometimes when Python is embedded or run from a symlink. The default value of each subkey of "[HKCU|HKLM]\Software\Python\PythonCore\\PythonPath", on the other hand, usually does extend sys.path. Except that running Python with the -E or -I command-line options (both supported by Python 3.4) makes the interpreter ignore PYTHON* environment variables, including PYTHONPATH, as well as registry settings such as subkeys of "PythonPath". Even with the -E or -I command-line options, .pth files in the system site-packages are still processed. A .pth file can be used to extend sys.path as long as the site module is imported, i.e. as long as the -S command-line option isn't used. One difference, however, is that directories in .pth files are appended to sys.path and thus do not override the standard library. From list1 at tompassin.net Sun May 14 19:04:08 2023 From: list1 at tompassin.net (Thomas Passin) Date: Sun, 14 May 2023 19:04:08 -0400 Subject: PythonPath / sys.path In-Reply-To: <64612FE4.15459.124FD5F@RealGrizzlyAdams.vivaldi.net> References: <645F69AC.14631.33F7F4@RealGrizzlyAdams.vivaldi.net> <12B1206B-7773-4870-B3CC-93126AEEFC70@barrys-emacs.org> <64612FE4.15459.124FD5F@RealGrizzlyAdams.vivaldi.net> Message-ID: <61608167-dd66-485c-33ee-f2c4292354bf@tompassin.net> On 5/14/2023 3:00 PM, Grizzy Adams via Python-list wrote: > Sunday, May 14, 2023 at 11:11, Mats Wichmann wrote: > Re: PythonPath / sys.path (at least in part) [snip] > I have since moved up (a little) so only ~4 years old, I then updated pip from > 9.x to 19.1 > > reason its an old version is it's an old PC (XpPro), if I start to get passable > > at this I will try it on my Ubuntu box which is running 22.04 (latest LTS) and > 23.04, (23.10 daily builds soon) I took a look and it seems I "may" have to > play a little to get IDLE on (if it's not in the normal repo's) > > I seem to have managed to sort "PythonPath / sys.path" the environment variable > > is working, so I can now import my_work without any other hassle, which is > good, now I find that some of the files which worked a treat from GUI, Editor > (F5) or terminal but don't do the same once saved and imported later, I'm sure > it's me, I have come from VB/VBA, Delphi and a (very) little C++, and am still > working through the python tutorial, trying not to skip ahead (ok I did skip > "Hello World" :->) so I may end up asking some (senior moment) newbie > questions, I will try hard to work it out myself first > > Thanks to all who got me thus far Good to hear you can run your program. For future reference, when you talked about setting PYTHONPATH, it would have been helpful to know just what you did when you tried to set it. If you plan to use this directory location much of the time, two good ways to do so are 1) putting that path in a .pth file in the site-packages directory, or 2) launching Python using a batch file that sets PYTHONPATH first, then runs Python. On Windows, in a batch file you should use SETLOCAL before setting PYTHONPATH and ENDLOCAL at the end of the batch file. That's the easiest way to remove the PYTHONPATH variable after you are done with it. You made a little slam against Windows, but you will find it harder to get things working on Linux. Ubuntu, like many other Linux distros, does not come with pip and Tk (needed for Idle) installed, and it's not so obvious how to install them. For your old computer, I added an external 1TB solid state drive (Note: not a usb stick) to a decade-old Sony VAIO and installed Linux Mint to the SSD. It's got pretty decent responsiveness and all the old hardware is supported out of the box. From rosuav at gmail.com Sun May 14 19:28:26 2023 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 15 May 2023 09:28:26 +1000 Subject: PythonPath / sys.path In-Reply-To: <61608167-dd66-485c-33ee-f2c4292354bf@tompassin.net> References: <645F69AC.14631.33F7F4@RealGrizzlyAdams.vivaldi.net> <12B1206B-7773-4870-B3CC-93126AEEFC70@barrys-emacs.org> <64612FE4.15459.124FD5F@RealGrizzlyAdams.vivaldi.net> <61608167-dd66-485c-33ee-f2c4292354bf@tompassin.net> Message-ID: On Mon, 15 May 2023 at 09:22, Thomas Passin wrote: > You made a little slam against Windows, but you will find it harder to > get things working on Linux. Ubuntu, like many other Linux distros, > does not come with pip and Tk (needed for Idle) installed, and it's not > so obvious how to install them. The assumption on Linux is usually that you know how to use your system's package manager. And on Debian and Ubuntu specifically, it's about as easy as you would want: "apt install idle". That'll pull in everything you should need. I don't know about other distros but I would expect that it's approximately as easy. Maybe that's not obvious if you come from Windows, but I'd guess that most desktop Linux users will have at least a passing familiarity with their package manager, making this a perfectly obvious way to get new software. ChrisA From list1 at tompassin.net Sun May 14 21:28:03 2023 From: list1 at tompassin.net (Thomas Passin) Date: Sun, 14 May 2023 21:28:03 -0400 Subject: PythonPath / sys.path In-Reply-To: References: <645F69AC.14631.33F7F4@RealGrizzlyAdams.vivaldi.net> <12B1206B-7773-4870-B3CC-93126AEEFC70@barrys-emacs.org> <64612FE4.15459.124FD5F@RealGrizzlyAdams.vivaldi.net> <61608167-dd66-485c-33ee-f2c4292354bf@tompassin.net> Message-ID: On 5/14/2023 7:28 PM, Chris Angelico wrote: > On Mon, 15 May 2023 at 09:22, Thomas Passin wrote: >> You made a little slam against Windows, but you will find it harder to >> get things working on Linux. Ubuntu, like many other Linux distros, >> does not come with pip and Tk (needed for Idle) installed, and it's not >> so obvious how to install them. > > The assumption on Linux is usually that you know how to use your > system's package manager. And on Debian and Ubuntu specifically, it's > about as easy as you would want: "apt install idle". That'll pull in > everything you should need. I don't know about other distros but I > would expect that it's approximately as easy. > > Maybe that's not obvious if you come from Windows, but I'd guess that > most desktop Linux users will have at least a passing familiarity with > their package manager, making this a perfectly obvious way to get new > software. Well, no, why would you assume that? I started to use Linux - in VMs - because I had to make sure that my cross-platform java/jython Tomcat program would work right on Linux. Why, for example, would I think to install Idle from the package manager when it, or things like that, were always in my experience installed with pip? For that matter, "sudo apt-get install pip" won't install pip. You need to use a different name, and it may or may not be different for different distros. No, I came to use Linux they way I said, but I didn't find those things to be obvious. That's why I've started mentioning them on this list when it seems like they might be useful. Furthermore, people have been having trouble getting certain PyQt programs working on Ubuntu 22.04 (and 20.xx before it) (yes, I know, not what the OP asked about). The solution is pretty non-obvious and requires a particular .so library file to be installed, if you can discover which one and how to do that. I mention this in support of what I said about a Windows Python user being likely to find things harder, not easier, on Linux. And please, let's not start a flame war about this! I'm passing on what I've experienced, that's all. Yes, I know that there are some Python packages that need to be built and that usually works better on Linux. And I'll agree that some Python programs are snappier to load and run on Linux than on the same machine running Windows, even in a Linux VM guest. From rosuav at gmail.com Sun May 14 23:08:51 2023 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 15 May 2023 13:08:51 +1000 Subject: PythonPath / sys.path In-Reply-To: References: <645F69AC.14631.33F7F4@RealGrizzlyAdams.vivaldi.net> <12B1206B-7773-4870-B3CC-93126AEEFC70@barrys-emacs.org> <64612FE4.15459.124FD5F@RealGrizzlyAdams.vivaldi.net> <61608167-dd66-485c-33ee-f2c4292354bf@tompassin.net> Message-ID: On Mon, 15 May 2023 at 12:07, Thomas Passin wrote: > Well, no, why would you assume that? I started to use Linux - in VMs - > because I had to make sure that my cross-platform java/jython Tomcat > program would work right on Linux. Why, for example, would I think to > install Idle from the package manager when it, or things like that, were > always in my experience installed with pip? For that matter, "sudo > apt-get install pip" won't install pip. You need to use a different > name, and it may or may not be different for different distros. If you EVER had to install something other than a Python package, you would have had to make use of the system package manager. You're right, there are multiple obvious ways to install Idle, but that doesn't mean that the package manager isn't one of them. ChrisA From list1 at tompassin.net Mon May 15 00:26:47 2023 From: list1 at tompassin.net (Thomas Passin) Date: Mon, 15 May 2023 00:26:47 -0400 Subject: PythonPath / sys.path In-Reply-To: References: <645F69AC.14631.33F7F4@RealGrizzlyAdams.vivaldi.net> <12B1206B-7773-4870-B3CC-93126AEEFC70@barrys-emacs.org> <64612FE4.15459.124FD5F@RealGrizzlyAdams.vivaldi.net> <61608167-dd66-485c-33ee-f2c4292354bf@tompassin.net> Message-ID: On 5/14/2023 11:08 PM, Chris Angelico wrote: > On Mon, 15 May 2023 at 12:07, Thomas Passin wrote: >> Well, no, why would you assume that? I started to use Linux - in VMs - >> because I had to make sure that my cross-platform java/jython Tomcat >> program would work right on Linux. Why, for example, would I think to >> install Idle from the package manager when it, or things like that, were >> always in my experience installed with pip? For that matter, "sudo >> apt-get install pip" won't install pip. You need to use a different >> name, and it may or may not be different for different distros. > > If you EVER had to install something other than a Python package, you > would have had to make use of the system package manager. You're > right, there are multiple obvious ways to install Idle, but that > doesn't mean that the package manager isn't one of them. Yes, after a while I came to realize that missing Python pieces might be available from the package manager. That doesn't mean it's obvious, or easy to discover just what names to use. And sometimes one has to add a new external repository. Personally, I don't find it easy to scroll through hundreds of lines in the synaptics search results looking for something whose name I can only partly guess at. If I know the command line equivalent for a search, I could do a grep and that would probably be more focused. But trying to work with a dozen different distros because various clients might use them - it's hard to keep details straight. Anyway, there's no point in trying to convince me that I could have understood everything at the start that I may have learned later. I'm just interested in passing on things I've learned along that way that a newcomer to Python in Linux may not realize. From barry at barrys-emacs.org Mon May 15 03:26:24 2023 From: barry at barrys-emacs.org (Barry) Date: Mon, 15 May 2023 08:26:24 +0100 Subject: PythonPath / sys.path In-Reply-To: References: Message-ID: > On 15 May 2023, at 05:39, Thomas Passin wrote: > > ?On 5/14/2023 11:08 PM, Chris Angelico wrote: >>> On Mon, 15 May 2023 at 12:07, Thomas Passin wrote: >>> Well, no, why would you assume that? I started to use Linux - in VMs - >>> because I had to make sure that my cross-platform java/jython Tomcat >>> program would work right on Linux. Why, for example, would I think to >>> install Idle from the package manager when it, or things like that, were >>> always in my experience installed with pip? For that matter, "sudo >>> apt-get install pip" won't install pip. You need to use a different >>> name, and it may or may not be different for different distros. >> If you EVER had to install something other than a Python package, you >> would have had to make use of the system package manager. You're >> right, there are multiple obvious ways to install Idle, but that >> doesn't mean that the package manager isn't one of them. > > Yes, after a while I came to realize that missing Python pieces might be available from the package manager. That doesn't mean it's obvious, or easy to discover just what names to use. And sometimes one has to add a new external repository. Personally, I don't find it easy to scroll through hundreds of lines in the synaptics search results looking for something whose name I can only partly guess at. If I know the command line equivalent for a search, I could do a grep and that would probably be more focused. But trying to work with a dozen different distros because various clients might use them - it's hard to keep details straight. > > Anyway, there's no point in trying to convince me that I could have understood everything at the start that I may have learned later. I'm just interested in passing on things I've learned along that way that a newcomer to Python in Linux may not realize. Being a Fedora user i needed to learn how to install missing pieces of pyrhon on ubuntu. We searches for: ubuntu install pip Ubuntu install idle Both provide lots of answers. Did your searches fail to turn up answers? Barry > > -- > https://mail.python.org/mailman/listinfo/python-list > From rosuav at gmail.com Mon May 15 03:28:46 2023 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 15 May 2023 17:28:46 +1000 Subject: PythonPath / sys.path In-Reply-To: References: <645F69AC.14631.33F7F4@RealGrizzlyAdams.vivaldi.net> <12B1206B-7773-4870-B3CC-93126AEEFC70@barrys-emacs.org> <64612FE4.15459.124FD5F@RealGrizzlyAdams.vivaldi.net> <61608167-dd66-485c-33ee-f2c4292354bf@tompassin.net> Message-ID: On Mon, 15 May 2023 at 14:38, Thomas Passin wrote: > > On 5/14/2023 11:08 PM, Chris Angelico wrote: > > On Mon, 15 May 2023 at 12:07, Thomas Passin wrote: > >> Well, no, why would you assume that? I started to use Linux - in VMs - > >> because I had to make sure that my cross-platform java/jython Tomcat > >> program would work right on Linux. Why, for example, would I think to > >> install Idle from the package manager when it, or things like that, were > >> always in my experience installed with pip? For that matter, "sudo > >> apt-get install pip" won't install pip. You need to use a different > >> name, and it may or may not be different for different distros. > > > > If you EVER had to install something other than a Python package, you > > would have had to make use of the system package manager. You're > > right, there are multiple obvious ways to install Idle, but that > > doesn't mean that the package manager isn't one of them. > > Yes, after a while I came to realize that missing Python pieces might be > available from the package manager. That doesn't mean it's obvious, or > easy to discover just what names to use. Define "obvious". Nothing is completely intuitive, and at some point, you HAVE to learn things. With any modern GUI desktop system, I am going to assume that "click on the thing" counts as obvious, even though it, like everything else, has to be learned. Once it's been the exact same UI for everything so far, wouldn't it count as obvious? Use your package manager. > And sometimes one has to add a > new external repository. Why? When do you need to? Use the system package manager and the core repositories. > Personally, I don't find it easy to scroll > through hundreds of lines in the synaptics search results looking for > something whose name I can only partly guess at. I don't use Synaptic, so I have no idea what the problem is here, but there are really only a couple of plausible package names: 1) idle 2) python-idle It's possible you'll need to install idle3 or python3-idle to get the latest, but if so, one of the above names would have installed Idle from Python 2.7. This is a matter of learning patterns, which most humans are good at. But even if you haven't yet, your absolute worst case is a straight-forward search ("apt-cache search idle", "apt search idle", or using a GUI tool to search). Assuming you haven't added every repository you can find, in a wild attempt to worsen your computer's stability and security, this should produce roughly a hundred results (I got 123 on my search), many of which are clearly not what you want. This is really not that many to skim over. > If I know the command > line equivalent for a search, I could do a grep and that would probably > be more focused. Did you try searching the web for "apt search for package" or anything like that? The command is "apt search" or "apt-cache search" (they're slightly different in output but they'll give broadly the same info) and this information is easily found on the internet. > But trying to work with a dozen different distros > because various clients might use them - it's hard to keep details straight. Okay, that's fair. You should only have to work with a small number of package managers, but the more different the distros are, the less effective you'll be at intuitively guessing the package names. But you should still be able to search. > Anyway, there's no point in trying to convince me that I could have > understood everything at the start that I may have learned later. I'm > just interested in passing on things I've learned along that way that a > newcomer to Python in Linux may not realize. I'm not saying you should have understood everything at the start; but I am saying that all the answers are out there if you look for them. Making blanket statements like: > Ubuntu, like many other Linux distros, > does not come with pip and Tk (needed for Idle) installed, and it's not > so obvious how to install them. are *EXTREMELY* unfair, since you are naming a single distro and then blaming "many other" distros by association, giving the highly false impression that Linux is nearly impossible to use. It is, in fact, very easy to install these things on many Linux distros. You just have to be willing to get to know your own system (since most people are only running one distro). ChrisA From list1 at tompassin.net Mon May 15 06:58:17 2023 From: list1 at tompassin.net (Thomas Passin) Date: Mon, 15 May 2023 06:58:17 -0400 Subject: PythonPath / sys.path In-Reply-To: References: Message-ID: On 5/15/2023 3:26 AM, Barry wrote: > > >> On 15 May 2023, at 05:39, Thomas Passin wrote: >> >> ?On 5/14/2023 11:08 PM, Chris Angelico wrote: >>>> On Mon, 15 May 2023 at 12:07, Thomas Passin wrote: >>>> Well, no, why would you assume that? I started to use Linux - in VMs - >>>> because I had to make sure that my cross-platform java/jython Tomcat >>>> program would work right on Linux. Why, for example, would I think to >>>> install Idle from the package manager when it, or things like that, were >>>> always in my experience installed with pip? For that matter, "sudo >>>> apt-get install pip" won't install pip. You need to use a different >>>> name, and it may or may not be different for different distros. >>> If you EVER had to install something other than a Python package, you >>> would have had to make use of the system package manager. You're >>> right, there are multiple obvious ways to install Idle, but that >>> doesn't mean that the package manager isn't one of them. >> >> Yes, after a while I came to realize that missing Python pieces might be available from the package manager. That doesn't mean it's obvious, or easy to discover just what names to use. And sometimes one has to add a new external repository. Personally, I don't find it easy to scroll through hundreds of lines in the synaptics search results looking for something whose name I can only partly guess at. If I know the command line equivalent for a search, I could do a grep and that would probably be more focused. But trying to work with a dozen different distros because various clients might use them - it's hard to keep details straight. >> >> Anyway, there's no point in trying to convince me that I could have understood everything at the start that I may have learned later. I'm just interested in passing on things I've learned along that way that a newcomer to Python in Linux may not realize. > > Being a Fedora user i needed to learn how to install missing pieces of pyrhon on ubuntu. > > We searches for: > ubuntu install pip > Ubuntu install idle > > Both provide lots of answers. Did your searches fail to turn up answers? No, that's what I had to do too, that and scan through package manager searches. From grant.b.edwards at gmail.com Mon May 15 17:11:37 2023 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Mon, 15 May 2023 14:11:37 -0700 (PDT) Subject: What to use instead of nntplib? Message-ID: <6462a009.050a0220.60724.3315@mx.google.com> I got a nice warning today from the inews utility I use daily: DeprecationWarning: 'nntplib' is deprecated and slated for removal in Python 3.13 What should I use in place of nntplib? -- Grant From skip.montanaro at gmail.com Mon May 15 17:50:44 2023 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Mon, 15 May 2023 16:50:44 -0500 Subject: What to use instead of nntplib? In-Reply-To: <6462a009.050a0220.60724.3315@mx.google.com> References: <6462a009.050a0220.60724.3315@mx.google.com> Message-ID: > I got a nice warning today from the inews utility I use daily: > > DeprecationWarning: 'nntplib' is deprecated and slated for removal in Python 3.13 > > What should I use in place of nntplib? I'd recommend creating a PyPI project with the existing 3.12 code, then using that from 3.13 onward. Skip From grant.b.edwards at gmail.com Mon May 15 22:12:38 2023 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Mon, 15 May 2023 19:12:38 -0700 (PDT) Subject: What to use instead of nntplib? References: <6462a009.050a0220.60724.3315@mx.google.com> Message-ID: <6462e696.920a0220.8160e.744a@mx.google.com> On 2023-05-15, Skip Montanaro wrote: >> I got a nice warning today from the inews utility I use daily: >> >> DeprecationWarning: 'nntplib' is deprecated and slated for >> removal in Python 3.13 >> >> What should I use in place of nntplib? > > I'd recommend creating a PyPI project with the existing 3.12 code, > then using that from 3.13 onward. That may be the easiest option. :/ I did some googling for utilities to post articles to NNTP servers and found "postnews". Of course it's written in Python and depends on nntplib... From learn2program at gmail.com Tue May 16 04:26:34 2023 From: learn2program at gmail.com (Alan Gauld) Date: Tue, 16 May 2023 09:26:34 +0100 Subject: What to use instead of nntplib? In-Reply-To: <6462a009.050a0220.60724.3315@mx.google.com> References: <6462a009.050a0220.60724.3315@mx.google.com> Message-ID: <469aa006-40d4-38c8-5776-fe0f9e908cf1@yahoo.co.uk> On 15/05/2023 22:11, Grant Edwards wrote: > I got a nice warning today from the inews utility I use daily: > > DeprecationWarning: 'nntplib' is deprecated and slated for removal in Python 3.13 > > What should I use in place of nntplib? I'm curious as to why nntplib is deprecated? Surely there are still a lot of nntp servers around, both inside and outside corporate firewalls? Is there a problem with the module or is it just perceived as no longer required? -- 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 cs at cskk.id.au Tue May 16 05:06:38 2023 From: cs at cskk.id.au (Cameron Simpson) Date: Tue, 16 May 2023 19:06:38 +1000 Subject: What to use instead of nntplib? In-Reply-To: <469aa006-40d4-38c8-5776-fe0f9e908cf1@yahoo.co.uk> References: <469aa006-40d4-38c8-5776-fe0f9e908cf1@yahoo.co.uk> Message-ID: On 16May2023 09:26, Alan Gauld wrote: >On 15/05/2023 22:11, Grant Edwards wrote: >> I got a nice warning today from the inews utility I use daily: >> >> DeprecationWarning: 'nntplib' is deprecated and slated for removal in Python 3.13 >> >> What should I use in place of nntplib? > >I'm curious as to why nntplib is deprecated? Surely there are still a >lot of nntp servers around, both inside and outside corporate firewalls? >Is there a problem with the module or is it just perceived as no longer >required? See PEP 594: https://peps.python.org/pep-0594/ From RealGrizzlyAdams at vivaldi.net Tue May 16 05:38:25 2023 From: RealGrizzlyAdams at vivaldi.net (Grizzy Adams) Date: Tue, 16 May 2023 10:38:25 +0100 Subject: What to use instead of nntplib? In-Reply-To: <469aa006-40d4-38c8-5776-fe0f9e908cf1@yahoo.co.uk> References: <6462a009.050a0220.60724.3315@mx.google.com>, <469aa006-40d4-38c8-5776-fe0f9e908cf1@yahoo.co.uk> Message-ID: <64634F11.6369.1A7139@RealGrizzlyAdams.vivaldi.net> Tuesday, May 16, 2023 at 9:26, Alan Gauld wrote: Re: What to use instead of nntplib? (at least in part) >On 15/05/2023 22:11, Grant Edwards wrote: >> I got a nice warning today from the inews utility I use daily: >> >> DeprecationWarning: 'nntplib' is deprecated and slated for removal in Python 3.13 >> >> What should I use in place of nntplib? >I'm curious as to why nntplib is deprecated? Surely there are still a >lot of nntp servers around there must be this list is mirrored on one, and AFAICS some pythoners use that way to post (over the list) From learn2program at gmail.com Tue May 16 06:48:33 2023 From: learn2program at gmail.com (Alan Gauld) Date: Tue, 16 May 2023 11:48:33 +0100 Subject: What to use instead of nntplib? In-Reply-To: References: <469aa006-40d4-38c8-5776-fe0f9e908cf1@yahoo.co.uk> Message-ID: <960340a9-2f55-9e48-4bb3-b39352387935@gmail.com> On 16/05/2023 10:06, Cameron Simpson wrote: >> I'm curious as to why nntplib is deprecated? Surely there are still a >> lot of nntp servers around, both inside and outside corporate firewalls? >> Is there a problem with the module or is it just perceived as no longer >> required? > > See PEP 594: https://peps.python.org/pep-0594/ Thanks Cameron. A scary list; I must have a dozen projects from the late 90s still live that are using many of these! I'm glad I'm retired and won't be the one who has to fix 'em :-) -- 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 mats at wichmann.us Tue May 16 09:07:45 2023 From: mats at wichmann.us (Mats Wichmann) Date: Tue, 16 May 2023 07:07:45 -0600 Subject: What to use instead of nntplib? In-Reply-To: <6462e696.920a0220.8160e.744a@mx.google.com> References: <6462a009.050a0220.60724.3315@mx.google.com> <6462e696.920a0220.8160e.744a@mx.google.com> Message-ID: <330a90f5-5078-bb6e-3a89-89f5a60a6e5a@wichmann.us> On 5/15/23 20:12, Grant Edwards wrote: > On 2023-05-15, Skip Montanaro wrote: >>> I got a nice warning today from the inews utility I use daily: >>> >>> DeprecationWarning: 'nntplib' is deprecated and slated for >>> removal in Python 3.13 >>> >>> What should I use in place of nntplib? >> >> I'd recommend creating a PyPI project with the existing 3.12 code, >> then using that from 3.13 onward. > > That may be the easiest option. :/ > > I did some googling for utilities to post articles to NNTP servers and > found "postnews". Of course it's written in Python and depends on > nntplib... > Should mention that there was a thread on this at discuss.python.org. Which seems to have petered out without a real resolution. https://discuss.python.org/t/allow-nntplib-on-pypi/25786 From grant.b.edwards at gmail.com Tue May 16 09:33:35 2023 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Tue, 16 May 2023 06:33:35 -0700 (PDT) Subject: What to use instead of nntplib? References: <469aa006-40d4-38c8-5776-fe0f9e908cf1@yahoo.co.uk> <960340a9-2f55-9e48-4bb3-b39352387935@gmail.com> Message-ID: <6463862f.020a0220.21ee1.48db@mx.google.com> On 2023-05-16, Alan Gauld wrote: > On 16/05/2023 10:06, Cameron Simpson wrote: > >>> I'm curious as to why nntplib is deprecated? Surely there are still a >>> lot of nntp servers around, both inside and outside corporate firewalls? Anything not used to develop AI is going to be depricated. An AI told me, so it must be true. >>> Is there a problem with the module or is it just perceived as no longer >>> required? Two issues were cited: 1. It's too stable, bug-free, and feature-complete. IOW "no activity". Apparently, people equate "activity" with "usage". 2. A problem with automated testing, since there's no server side support. Though testing a module's client implementation by having it talk to a module's server implementation seems like a singularly bad idea. >> See PEP 594: https://peps.python.org/pep-0594/ > > Thanks Cameron. > A scary list; I must have a dozen projects from the late 90s still > live that are using many of these! I'm glad I'm retired and won't > be the one who has to fix 'em :-) It has been pointed out to me that Perl still has a supported NNTP library. That stung. However, it's a CPAN module, which is more equivalent to PyPI than to the standard library, so I guess that it isn't as bad a loss of face as I feared. -- Grant From cl at isbd.net Tue May 16 06:56:39 2023 From: cl at isbd.net (Chris Green) Date: Tue, 16 May 2023 11:56:39 +0100 Subject: What to use instead of nntplib? References: <6462a009.050a0220.60724.3315@mx.google.com> <469aa006-40d4-38c8-5776-fe0f9e908cf1@yahoo.co.uk> <64634F11.6369.1A7139@RealGrizzlyAdams.vivaldi.net> Message-ID: <744cjj-9dqi3.ln1@esprimo.zbmc.eu> Grizzy Adams wrote: > Tuesday, May 16, 2023 at 9:26, Alan Gauld wrote: > Re: What to use instead of nntplib? (at least in part) > > >On 15/05/2023 22:11, Grant Edwards wrote: > >> I got a nice warning today from the inews utility I use daily: > >> > >> DeprecationWarning: 'nntplib' is deprecated and slated for removal in Python 3.13 > >> > >> What should I use in place of nntplib? > > >I'm curious as to why nntplib is deprecated? Surely there are still a > >lot of nntp servers around > > there must be this list is mirrored on one, and AFAICS some pythoners use that > way to post (over the list) Yes, me for one, a good newsreader is really a wonderful way to manage technical 'lists' like this one. Usenet news is still very much alive though a minority interest now I suspect. -- Chris Green ? From grant.b.edwards at gmail.com Tue May 16 11:14:37 2023 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Tue, 16 May 2023 08:14:37 -0700 (PDT) Subject: What to use instead of nntplib? References: <6462a009.050a0220.60724.3315@mx.google.com> <469aa006-40d4-38c8-5776-fe0f9e908cf1@yahoo.co.uk> <64634F11.6369.1A7139@RealGrizzlyAdams.vivaldi.net> <744cjj-9dqi3.ln1@esprimo.zbmc.eu> Message-ID: <64639ddd.020a0220.4bd44.83fd@mx.google.com> On 2023-05-16, Chris Green wrote: > Grizzy Adams wrote: >> Tuesday, May 16, 2023 at 9:26, Alan Gauld wrote: >> Re: What to use instead of nntplib? (at least in part) >> >> >On 15/05/2023 22:11, Grant Edwards wrote: >> >> I got a nice warning today from the inews utility I use daily: >> >> >> >> DeprecationWarning: 'nntplib' is deprecated and slated for removal in Python 3.13 >> >> >> >> What should I use in place of nntplib? >> >> >I'm curious as to why nntplib is deprecated? Surely there are still a >> >lot of nntp servers around >> >> there must be this list is mirrored on one, and AFAICS some pythoners use that >> way to post (over the list) > > Yes, me for one, a good newsreader is really a wonderful way to manage > technical 'lists' like this one. IMO, there's nothing better. Newsreaders were designed from the beginning to deal with the sort of traffic and usage patterns seen in mailing lists. Using an MUA (even combined with something like procmail) and folders/labels is just a pale imitation of a good newsreader. > Usenet news is still very much alive though a minority interest now > I suspect. This list's decision to stop accepting postings via news.gmane.io is what prompted me to write my own "inews" application in Python that uses SMTP for some groups and NNTP for others when I "post" via slrn. I probably use NNTP more to access mailing lists via gmane than I use it for accessing the "real" Usenet groups. NNTP is not just for Usenet... From aysumammedlii7 at gmail.com Wed May 17 10:54:26 2023 From: aysumammedlii7 at gmail.com (Aysu Mammadli) Date: Wed, 17 May 2023 17:54:26 +0300 Subject: Pip Error Message-ID: I encountered an error while attempting to install pip using the terminal. The exact error message I received is: "An error occurred during configuration: option use-feature: invalid choice: '2020-resolver' (choose from 'fast-deps', 'truststore', 'no-binary-enable-wheel-cache')" Here are the steps I followed and the context of my system: Operating System: Windows 11 Python Version: 3.11.3 I executed the command in the terminal to install pip, but it resulted in the aforementioned error message. This error specifically references the '2020-resolver' choice within the 'use-feature' option. An error occurred during configuration: option use-feature: invalid choice: '2020-resolver' (choose from 'fast-deps', 'truststore', 'no-binary-enable-wheel-cache') I have already attempted the following troubleshooting steps without success: Checked my internet connectivity to ensure it was stable and not causing any issues. Verified that I have the latest version of pip installed, as well as the latest version of Python. Tried using alternative commands, such as using the --upgrade flag or specifying a specific pip version, but the error persists. Looked for any recent system updates or changes that could have caused this issue, but found none. I'm uncertain about the cause of this error and how to resolve it. Any insights or suggestions would be greatly appreciated. Thank you in advance for your assistance! From barry at barrys-emacs.org Wed May 17 13:24:40 2023 From: barry at barrys-emacs.org (Barry) Date: Wed, 17 May 2023 18:24:40 +0100 Subject: Pip Error In-Reply-To: References: Message-ID: <8DE43BD6-E04D-4CDD-A7FA-388F5ACF0441@barrys-emacs.org> > On 17 May 2023, at 17:26, Aysu Mammadli wrote: > > ?I encountered an error while attempting to install pip using the terminal. > The exact error message I received is: > > "An error occurred during configuration: option use-feature: invalid > choice: '2020-resolver' (choose from 'fast-deps', 'truststore', > 'no-binary-enable-wheel-cache')" > > Here are the steps I followed and the context of my system: > > Operating System: Windows 11 Python Version: 3.11.3 I executed the command > in the terminal to install pip, but it resulted in the aforementioned error > message. This error specifically references the '2020-resolver' choice > within the 'use-feature' option. An error occurred during configuration: > option use-feature: invalid choice: '2020-resolver' (choose from > 'fast-deps', 'truststore', 'no-binary-enable-wheel-cache') > > I have already attempted the following troubleshooting steps without > success: > > Checked my internet connectivity to ensure it was stable and not causing > any issues. Verified that I have the latest version of pip installed, as > well as the latest version of Python. Tried using alternative commands, > such as using the --upgrade flag or specifying a specific pip version, but > the error persists. Looked for any recent system updates or changes that > could have caused this issue, but found none. I'm uncertain about the cause > of this error and how to resolve it. Any insights or suggestions would be > greatly appreciated. > > Thank you in advance for your assistance! Pip is installed by default with the python.org kits. I am not sure what the situation is for the app store python. Can you run python it self? Does one of these work for you? py -m pip python -m pip If so you have pip installed. Barry > -- > https://mail.python.org/mailman/listinfo/python-list > From list1 at tompassin.net Wed May 17 13:25:30 2023 From: list1 at tompassin.net (Thomas Passin) Date: Wed, 17 May 2023 13:25:30 -0400 Subject: Pip Error In-Reply-To: References: Message-ID: <1e3abf2b-5600-b9e3-fea1-154223cb5c11@tompassin.net> On 5/17/2023 10:54 AM, Aysu Mammadli wrote: > I encountered an error while attempting to install pip using the terminal. > The exact error message I received is: > > "An error occurred during configuration: option use-feature: invalid > choice: '2020-resolver' (choose from 'fast-deps', 'truststore', > 'no-binary-enable-wheel-cache')" > > Here are the steps I followed and the context of my system: > > Operating System: Windows 11 Python Version: 3.11.3 I executed the command > in the terminal to install pip, but it resulted in the aforementioned error > message. This error specifically references the '2020-resolver' choice > within the 'use-feature' option. An error occurred during configuration: > option use-feature: invalid choice: '2020-resolver' (choose from > 'fast-deps', 'truststore', 'no-binary-enable-wheel-cache') > > I have already attempted the following troubleshooting steps without > success: > > Checked my internet connectivity to ensure it was stable and not causing > any issues. Verified that I have the latest version of pip installed, as > well as the latest version of Python. Tried using alternative commands, > such as using the --upgrade flag or specifying a specific pip version, but > the error persists. Looked for any recent system updates or changes that > could have caused this issue, but found none. I'm uncertain about the cause > of this error and how to resolve it. Any insights or suggestions would be > greatly appreciated. > > Thank you in advance for your assistance! I don't remember needing to install pip with Windows installations. I've got 3.11.3 on Windows 10. The installer and source distro for Windows both come with the ensurepip module: -m ensurepip will install pip, where is the name of the version of Python you want to run. I assume (but don't know for sure) that the standard installer runs ensurepip as part of its work. How (and why) did you try to install it? The error is coming from Lib\site-packages\pip\_internal\cli\parser.py. It's possible that some inconsistency has crept in between the allowed options and the ones that are given to the parser. From jqian at tibco.com Wed May 17 15:32:23 2023 From: jqian at tibco.com (Jason Qian) Date: Wed, 17 May 2023 15:32:23 -0400 Subject: Help on ImportError('Error: Reinit is forbidden') Message-ID: Hi, I Need some of your help. I have the following C code to import *Import python.* It works 99% of the time, but sometimes receives "*ImportError('Error: Reinit is forbidden')*". error. **We run multiple instances of the app parallelly. *** Python version(3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC v.1914 64 bit (AMD64)] PyObject * importPythonModule(const char* pmodName) { const char* errors = NULL; int nlen = strlen(pmodName); PyObject *pName = PyUnicode_DecodeUTF8(pmodName, nlen, errors); PyObject *pModule = *PyImport_Import*(pName); Py_DECREF(pName); if (pModule == NULL) { if (*PyErr_Occurred*()) { handleError("PyImport_Import()"); } } } void handleError(const char* msg) { ... "PyImport_Import() - ImportError('Error: Reinit is forbidden')" } Thanks Jason From barry at barrys-emacs.org Thu May 18 03:53:44 2023 From: barry at barrys-emacs.org (Barry) Date: Thu, 18 May 2023 08:53:44 +0100 Subject: Help on ImportError('Error: Reinit is forbidden') In-Reply-To: References: Message-ID: <572AE481-352F-40A1-88F8-32A903F8325B@barrys-emacs.org> > On 17 May 2023, at 20:35, Jason Qian via Python-list wrote: > > ? Hi, > > I Need some of your help. > > I have the following C code to import *Import python.* It works 99% of > the time, but sometimes receives "*ImportError('Error: Reinit is > forbidden')*". error. > **We run multiple instances of the app parallelly. > > *** Python version(3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC > v.1914 64 bit (AMD64)] > > PyObject * importPythonModule(const char* pmodName) > { > const char* errors = NULL; > int nlen = strlen(pmodName); > PyObject *pName = PyUnicode_DecodeUTF8(pmodName, nlen, errors); > PyObject *pModule = *PyImport_Import*(pName); > Py_DECREF(pName); > if (pModule == NULL) { > if (*PyErr_Occurred*()) { > handleError("PyImport_Import()"); > } > } > } > void handleError(const char* msg) > { > ... > "PyImport_Import() - ImportError('Error: Reinit is forbidden')" > } You do not seem to printing out msg, you have assumed it means reinit it seems. What does msg contain when it fails? Barry > > > Thanks > Jason > -- > https://mail.python.org/mailman/listinfo/python-list > From rob.cliffe at btinternet.com Fri May 12 04:55:15 2023 From: rob.cliffe at btinternet.com (Rob Cliffe) Date: Fri, 12 May 2023 09:55:15 +0100 Subject: Learning tkinter Message-ID: <32e1bd95-9058-2896-2573-7e95d7aa1951@btinternet.com> I am trying to learn tkinter. Several examples on the internet refer to a messagebox class (tkinter.messagebox). But: Python 3.8.3 (tags/v3.8.3:6f8c832, May 13 2020, 22:20:19) [MSC v.1925 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import tkinter >>> tkinter.messagebox Traceback (most recent call last): ? File "", line 1, in AttributeError: module 'tkinter' has no attribute 'messagebox' >>> Why is this? TIA Rob Cliffe From jqian at tibco.com Thu May 18 08:55:53 2023 From: jqian at tibco.com (Jason Qian) Date: Thu, 18 May 2023 08:55:53 -0400 Subject: Help on ImportError('Error: Reinit is forbidden') In-Reply-To: <572AE481-352F-40A1-88F8-32A903F8325B@barrys-emacs.org> References: <572AE481-352F-40A1-88F8-32A903F8325B@barrys-emacs.org> Message-ID: Hi Barry, void handleError(const char* msg) { ... PyErr_Fetch(&pyExcType, &pyExcValue, &pyExcTraceback); PyErr_NormalizeException(&pyExcType, &pyExcValue, &pyExcTraceback); PyObject* str_value = PyObject_Repr(pyExcValue); PyObject* pyExcValueStr = PyUnicode_AsEncodedString(str_value, "utf-8", "Error ~"); const char **strErrValue* = PyBytes_AS_STRING(pyExcValueStr); //where *strErrValue* = "ImportError('Error: Reinit is forbidden')" ... } What we imported is a Python file which import some pyd libraries. Thanks Jason On Thu, May 18, 2023 at 3:53?AM Barry wrote: > > > > On 17 May 2023, at 20:35, Jason Qian via Python-list < > python-list at python.org> wrote: > > > > ? Hi, > > > > I Need some of your help. > > > > I have the following C code to import *Import python.* It works 99% of > > the time, but sometimes receives "*ImportError('Error: Reinit is > > forbidden')*". error. > > **We run multiple instances of the app parallelly. > > > > *** Python version(3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC > > v.1914 64 bit (AMD64)] > > > > PyObject * importPythonModule(const char* pmodName) > > { > > const char* errors = NULL; > > int nlen = strlen(pmodName); > > PyObject *pName = PyUnicode_DecodeUTF8(pmodName, nlen, errors); > > PyObject *pModule = *PyImport_Import*(pName); > > Py_DECREF(pName); > > if (pModule == NULL) { > > if (*PyErr_Occurred*()) { > > handleError("PyImport_Import()"); > > } > > } > > } > > void handleError(const char* msg) > > { > > ... > > "PyImport_Import() - ImportError('Error: Reinit is forbidden')" > > } > > You do not seem to printing out msg, you have assumed it means reinit it > seems. > What does msg contain when it fails? > > Barry > > > > > > Thanks > > Jason > > -- > > https://mail.python.org/mailman/listinfo/python-list > > > > From grant.b.edwards at gmail.com Thu May 18 09:13:52 2023 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Thu, 18 May 2023 06:13:52 -0700 (PDT) Subject: Learning tkinter References: <32e1bd95-9058-2896-2573-7e95d7aa1951@btinternet.com> Message-ID: <64662490.5e0a0220.9af28.052a@mx.google.com> On 2023-05-12, Rob Cliffe via Python-list wrote: > > Python 3.8.3 (tags/v3.8.3:6f8c832, May 13 2020, 22:20:19) [MSC v.1925 32 > bit (Intel)] on win32 > Type "help", "copyright", "credits" or "license" for more information. > >>> import tkinter > >>> tkinter.messagebox > Traceback (most recent call last): > ? File "", line 1, in > AttributeError: module 'tkinter' has no attribute 'messagebox' > >>> $ python Python 3.11.3 (main, May 8 2023, 09:00:54) [GCC 12.2.1 20230428] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import tkinter >>> from tkinter import messagebox >>> messagebox >>> > Why is this? Dunno. From oscar.j.benjamin at gmail.com Thu May 18 09:44:18 2023 From: oscar.j.benjamin at gmail.com (Oscar Benjamin) Date: Thu, 18 May 2023 14:44:18 +0100 Subject: Learning tkinter In-Reply-To: <32e1bd95-9058-2896-2573-7e95d7aa1951@btinternet.com> References: <32e1bd95-9058-2896-2573-7e95d7aa1951@btinternet.com> Message-ID: On Thu, 18 May 2023 at 10:16, Rob Cliffe via Python-list wrote: > > I am trying to learn tkinter. > Several examples on the internet refer to a messagebox class > (tkinter.messagebox). > But: > > Python 3.8.3 (tags/v3.8.3:6f8c832, May 13 2020, 22:20:19) [MSC v.1925 32 > bit (Intel)] on win32 > Type "help", "copyright", "credits" or "license" for more information. > >>> import tkinter > >>> tkinter.messagebox > Traceback (most recent call last): > File "", line 1, in > AttributeError: module 'tkinter' has no attribute 'messagebox' > >>> > > Why is this? Do you have a file called tkinter.py in the current directory? -- Oscar From rosuav at gmail.com Thu May 18 10:00:01 2023 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 19 May 2023 00:00:01 +1000 Subject: Learning tkinter In-Reply-To: <32e1bd95-9058-2896-2573-7e95d7aa1951@btinternet.com> References: <32e1bd95-9058-2896-2573-7e95d7aa1951@btinternet.com> Message-ID: On Thu, 18 May 2023 at 19:15, Rob Cliffe via Python-list wrote: > > I am trying to learn tkinter. > Several examples on the internet refer to a messagebox class > (tkinter.messagebox). > But: > > Python 3.8.3 (tags/v3.8.3:6f8c832, May 13 2020, 22:20:19) [MSC v.1925 32 > bit (Intel)] on win32 > Type "help", "copyright", "credits" or "license" for more information. > >>> import tkinter > >>> tkinter.messagebox > Traceback (most recent call last): > File "", line 1, in > AttributeError: module 'tkinter' has no attribute 'messagebox' > >>> > > Why is this? Is it possible that you've created a tkinter.py for your own tinkering? ChrisA From barry at barrys-emacs.org Thu May 18 10:17:49 2023 From: barry at barrys-emacs.org (Barry) Date: Thu, 18 May 2023 15:17:49 +0100 Subject: Help on ImportError('Error: Reinit is forbidden') In-Reply-To: References: Message-ID: <6AD2027C-6EBE-4C08-AAE7-93663CE484AA@barrys-emacs.org> On 18 May 2023, at 13:56, Jason Qian wrote: ? Hi?Barry, void handleError(const char* msg) { ... PyErr_Fetch(&pyExcType, &pyExcValue, &pyExcTraceback); PyErr_NormalizeException(&pyExcType, &pyExcValue, &pyExcTraceback); PyObject* str_value = PyObject_Repr(pyExcValue); PyObject* pyExcValueStr = PyUnicode_AsEncodedString(str_value, "utf-8", "Error ~"); const char *strErrValue = PyBytes_AS_STRING(pyExcValueStr); //where?? strErrValue???= "ImportError('Error: Reinit is forbidden')" ... } What we imported is a Python file which import some pyd libraries. Please do not top post replies. Ok so assume the error is correct and hunt for the code that does the reimport. You may need to set break points in you C code to find tnw caller. Barry Thanks? Jason? On Thu, May 18, 2023 at 3:53?AM Barry <[1]barry at barrys-emacs.org> wrote: > On 17 May 2023, at 20:35, Jason Qian via Python-list <[2]python-list at python.org> wrote: > > ? Hi, > >? ?I Need some of your help. > > I have the following C code to import *Import python.*? ?It works 99% of > the time, but sometimes? receives? "*ImportError('Error: Reinit is > forbidden')*". error. > **We run multiple instances of the app parallelly. > > *** Python version(3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC > v.1914 64 bit (AMD64)] > > PyObject * importPythonModule(const char* pmodName) > { >? ? const char* errors = NULL; >? ? ?int nlen = strlen(pmodName); >? ? ?PyObject *pName = PyUnicode_DecodeUTF8(pmodName, nlen, errors); >? ? ?PyObject *pModule = *PyImport_Import*(pName); >? ? ?Py_DECREF(pName); >? ? ?if (pModule == NULL) { >? ? ?if (*PyErr_Occurred*()) { >? ? ? ? ? ? handleError("PyImport_Import()"); >? ? ? } >? ?} > } > void handleError(const char* msg) > { >? ... >? "PyImport_Import() - ImportError('Error: Reinit is forbidden')" > } You do not seem to printing out msg, you have assumed it means reinit it seems. What does msg contain when it fails? Barry > > > Thanks > Jason > -- > [3]https://mail.python.org/mailman/listinfo/python-list > References Visible links 1. mailto:barry at barrys-emacs.org 2. mailto:python-list at python.org 3. https://mail.python.org/mailman/listinfo/python-list From jschwar at sbcglobal.net Thu May 18 10:50:38 2023 From: jschwar at sbcglobal.net (Jim Schwartz) Date: Thu, 18 May 2023 09:50:38 -0500 Subject: Learning tkinter In-Reply-To: <32e1bd95-9058-2896-2573-7e95d7aa1951@btinternet.com> References: <32e1bd95-9058-2896-2573-7e95d7aa1951@btinternet.com> Message-ID: <008101d98998$1d163810$5742a830$@sbcglobal.net> This works for me. Hope it helps. from tkinter import messagebox messagebox.showerror("Hi", f"Hello World") -----Original Message----- From: Python-list On Behalf Of Rob Cliffe via Python-list Sent: Friday, May 12, 2023 3:55 AM To: Python Subject: Learning tkinter I am trying to learn tkinter. Several examples on the internet refer to a messagebox class (tkinter.messagebox). But: Python 3.8.3 (tags/v3.8.3:6f8c832, May 13 2020, 22:20:19) [MSC v.1925 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import tkinter >>> tkinter.messagebox Traceback (most recent call last): File "", line 1, in AttributeError: module 'tkinter' has no attribute 'messagebox' >>> Why is this? TIA Rob Cliffe -- https://mail.python.org/mailman/listinfo/python-list From testonlyy5 at gmail.com Thu May 18 06:30:35 2023 From: testonlyy5 at gmail.com (Test Only) Date: Thu, 18 May 2023 03:30:35 -0700 Subject: Error installing packages or upgrading pip Message-ID: Hi there, I hope you are in a great health I am having a problem with python even though I uninstall and reinstall it again multiple times the error I get when I try to upgrade or install a package for example pip install requests I get this error which I could not find a solution for pip install requests Requirement already satisfied: requests in c:\users\uly\appdata\local\programs\python\python310\lib\site-packages\requests-2.30.0-py3.10.egg (2.30.0) WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProtocolError('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))': /simple/charset-normalizer/ WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProtocolError('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))': /simple/charset-normalizer/ WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProtocolError('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))': /simple/charset-normalizer/ WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProtocolError('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))': /simple/charset-normalizer/ WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProtocolError('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))': /simple/charset-normalizer/ WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProtocolError('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))': /simple/requests/ WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProtocolError('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))': /simple/requests/ WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProtocolError('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))': /simple/requests/ WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProtocolError('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))': /simple/requests/ WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProtocolError('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))': /simple/requests/ ERROR: Could not find a version that satisfies the requirement charset_normalizer<4,>=2 (from requests) (from versions: none) ERROR: No matching distribution found for charset_normalizer<4,>=2 WARNING: There was an error checking the latest version of pip. From list1 at tompassin.net Thu May 18 11:48:29 2023 From: list1 at tompassin.net (Thomas Passin) Date: Thu, 18 May 2023 11:48:29 -0400 Subject: Learning tkinter In-Reply-To: <64662490.5e0a0220.9af28.052a@mx.google.com> References: <32e1bd95-9058-2896-2573-7e95d7aa1951@btinternet.com> <64662490.5e0a0220.9af28.052a@mx.google.com> Message-ID: <53305858-bd73-a166-6398-a2ac77f62bf8@tompassin.net> On 5/18/2023 9:13 AM, Grant Edwards wrote: > On 2023-05-12, Rob Cliffe via Python-list wrote: >> >> Python 3.8.3 (tags/v3.8.3:6f8c832, May 13 2020, 22:20:19) [MSC v.1925 32 >> bit (Intel)] on win32 >> Type "help", "copyright", "credits" or "license" for more information. >>>>> import tkinter >>>>> tkinter.messagebox >> Traceback (most recent call last): >> ? File "", line 1, in >> AttributeError: module 'tkinter' has no attribute 'messagebox' >>>>> > > $ python > Python 3.11.3 (main, May 8 2023, 09:00:54) [GCC 12.2.1 20230428] on linux > Type "help", "copyright", "credits" or "license" for more information. >>>> import tkinter >>>> from tkinter import messagebox >>>> messagebox > >>>> > > >> Why is this? > > Dunno. tkinter is a package, messagebox is a module within the tkinter package. the messagebox module has some functions, such as showinfo(). You *can* import those functions using "dot" expressions: >>> from tkinter.messagebox import showinfo You can also import the entire module using the "dot" syntax: >>> import tkinter.messagebox >>> messagebox.showinfo Whether you can directly ask for tkinter.messagebox depends on whether it's been defined or imported in tkinter/__init__.py. From tdldev at gmail.com Thu May 18 12:06:36 2023 From: tdldev at gmail.com (Jack Dangler) Date: Thu, 18 May 2023 12:06:36 -0400 Subject: Tkinter (related)~ Message-ID: <13a1c77e-83b2-55ea-4c94-7636c3bd8d70@gmail.com> I didn't want to hijack another thread... I thought the OP of the tkinter thread currently running may have needed to install the tkinter package (since I had the same missing component error message), so I tried to install the package on to my Ubu laptop - pip install tkinter Defaulting to user installation because normal site-packages is not writeable ERROR: Could not find a version that satisfies the requirement tkinter (from versions: none) ERROR: No matching distribution found for tkinter Is there an alternate path to installing this? Thanks for any help you can provide... Jack From mats at wichmann.us Thu May 18 12:33:35 2023 From: mats at wichmann.us (Mats Wichmann) Date: Thu, 18 May 2023 10:33:35 -0600 Subject: Tkinter (related)~ In-Reply-To: <13a1c77e-83b2-55ea-4c94-7636c3bd8d70@gmail.com> References: <13a1c77e-83b2-55ea-4c94-7636c3bd8d70@gmail.com> Message-ID: <20d98bc1-7a94-bd0c-43f1-de81c2caf3d4@wichmann.us> On 5/18/23 10:06, Jack Dangler wrote: > I didn't want to hijack another thread... > > I thought the OP of the tkinter thread currently running may have needed > to install the tkinter package (since I had the same missing component > error message), so I tried to install the package on to my Ubu laptop - install python3-tk to get the distro package. From mats at wichmann.us Thu May 18 12:41:28 2023 From: mats at wichmann.us (Mats Wichmann) Date: Thu, 18 May 2023 10:41:28 -0600 Subject: Learning tkinter In-Reply-To: <008101d98998$1d163810$5742a830$@sbcglobal.net> References: <32e1bd95-9058-2896-2573-7e95d7aa1951@btinternet.com> <008101d98998$1d163810$5742a830$@sbcglobal.net> Message-ID: <3f38b5fc-d766-3f28-0f53-8b4bfd241f5e@wichmann.us> On 5/18/23 08:50, Jim Schwartz wrote: > This works for me. Hope it helps. > > from tkinter import messagebox > > messagebox.showerror("Hi", f"Hello World") It's probably instructive that IDLE always brings it in this way. Lib/idlelib/config_key.py:from tkinter import messagebox Lib/idlelib/configdialog.py:from tkinter import messagebox Lib/idlelib/editor.py:from tkinter import messagebox ... etc From tdldev at gmail.com Thu May 18 12:48:54 2023 From: tdldev at gmail.com (Jack Dangler) Date: Thu, 18 May 2023 12:48:54 -0400 Subject: Tkinter (related)~ In-Reply-To: <20d98bc1-7a94-bd0c-43f1-de81c2caf3d4@wichmann.us> References: <13a1c77e-83b2-55ea-4c94-7636c3bd8d70@gmail.com> <20d98bc1-7a94-bd0c-43f1-de81c2caf3d4@wichmann.us> Message-ID: On 5/18/23 12:33, Mats Wichmann wrote: > On 5/18/23 10:06, Jack Dangler wrote: >> I didn't want to hijack another thread... >> >> I thought the OP of the tkinter thread currently running may have >> needed to install the tkinter package (since I had the same missing >> component error message), so I tried to install the package on to my >> Ubu laptop - > > install python3-tk to get the distro package. > > Thanks, Mats! apt worked... I'll have another run at the original thread and see where that takes me. From python at mrabarnett.plus.com Thu May 18 13:31:15 2023 From: python at mrabarnett.plus.com (MRAB) Date: Thu, 18 May 2023 18:31:15 +0100 Subject: Learning tkinter In-Reply-To: <32e1bd95-9058-2896-2573-7e95d7aa1951@btinternet.com> References: <32e1bd95-9058-2896-2573-7e95d7aa1951@btinternet.com> Message-ID: On 2023-05-12 09:55, Rob Cliffe via Python-list wrote: > I am trying to learn tkinter. > Several examples on the internet refer to a messagebox class > (tkinter.messagebox). > But: > > Python 3.8.3 (tags/v3.8.3:6f8c832, May 13 2020, 22:20:19) [MSC v.1925 32 > bit (Intel)] on win32 > Type "help", "copyright", "credits" or "license" for more information. > >>> import tkinter > >>> tkinter.messagebox > Traceback (most recent call last): > ? File "", line 1, in > AttributeError: module 'tkinter' has no attribute 'messagebox' > >>> > > Why is this? It's a submodule of tkinter: >>> import tkinter.messagebox as mb >>> mb.showinfo From cs at cskk.id.au Thu May 18 20:53:37 2023 From: cs at cskk.id.au (Cameron Simpson) Date: Fri, 19 May 2023 10:53:37 +1000 Subject: Tkinter (related)~ In-Reply-To: <13a1c77e-83b2-55ea-4c94-7636c3bd8d70@gmail.com> References: <13a1c77e-83b2-55ea-4c94-7636c3bd8d70@gmail.com> Message-ID: On 18May2023 12:06, Jack Dangler wrote: >I thought the OP of the tkinter thread currently running may have >needed to install the tkinter package (since I had the same missing >component error message), so I tried to install the package on to my >Ubu laptop - > >pip install tkinter >Defaulting to user installation because normal site-packages is not >writeable >ERROR: Could not find a version that satisfies the requirement tkinter >(from versions: none) >ERROR: No matching distribution found for tkinter > >Is there an alternate path to installing this? Usually tkinter ships with Python because it is part of the stdlib. On some platforms eg Ubuntu Linux the stdlib doesn't come in completely unless you ask - a lot of stdlib packages are apt things you need to ask for. On my Ubunut here tkinter comes from python3-tk. So: $ sudo apt-get install python3-tk Cheers, Cameron Simpson From grant.b.edwards at gmail.com Thu May 18 21:11:22 2023 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Thu, 18 May 2023 18:11:22 -0700 (PDT) Subject: Tkinter (related)~ References: <13a1c77e-83b2-55ea-4c94-7636c3bd8d70@gmail.com> Message-ID: <6466ccba.920a0220.afe81.0bd0@mx.google.com> On 2023-05-19, Cameron Simpson wrote: > On 18May2023 12:06, Jack Dangler wrote: >>I thought the OP of the tkinter thread currently running may have >>needed to install the tkinter package (since I had the same missing >>component error message), so I tried to install the package on to my >>Ubu laptop - >> >>pip install tkinter >>Defaulting to user installation because normal site-packages is not >>writeable >>ERROR: Could not find a version that satisfies the requirement tkinter >>(from versions: none) >>ERROR: No matching distribution found for tkinter >> >>Is there an alternate path to installing this? > > Usually tkinter ships with Python because it is part of the stdlib. > > On some platforms eg Ubuntu Linux the stdlib doesn't come in completely > unless you ask - a lot of stdlib packages are apt things you need to ask > for. On my Ubunut here tkinter comes from python3-tk. So: > > $ sudo apt-get install python3-tk And in general, on Linux systems, you'll be better off in the long run if you use the distro's package manager to install Python packages instead of using pip. If there is no distro package, you're usually also better off using 'pip install --user' so that pip isn't messing about with directories that are normally managed by the distro's package manager. When I do have to resort to using pip in install something, I always do a --dry-run first and make a note of any dependancies that pip is going to try to install -- so I can install those using the package manager if possible. -- Grant From meejah at meejah.ca Thu May 18 21:37:06 2023 From: meejah at meejah.ca (meejah at meejah.ca) Date: Fri, 19 May 2023 01:37:06 GMT Subject: txtorcon 23.5.0 Message-ID: <6pA9M.276484$qjm2.29867@fx09.iad> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 I'm happy to announce txtorcon 23.5.0 with the following changes: * twisted.web.client.Agent instances now use the same HTTPS policy by default as twisted.web.client.Agent. It is possible to override this policy with the tls_context_factory= argument, the equivalent to Agent's contextFactory= (Thanks to Itamar Turner-Trauring) * Added support + testing for Python 3.11. * No more ipaddress dependency You can download the release from PyPI or GitHub (or of course "pip install txtorcon"): https://pypi.python.org/pypi/txtorcon/23.5.0 https://github.com/meejah/txtorcon/releases/tag/v23.5.0 Releases are also available from the hidden service: http://fjblvrw2jrxnhtg67qpbzi45r7ofojaoo3orzykesly2j3c2m3htapid.onion/txtorcon-23.5.0.tar.gz http://fjblvrw2jrxnhtg67qpbzi45r7ofojaoo3orzykesly2j3c2m3htapid.onion/txtorcon-23.5.0.tar.gz.asc You can verify the sha256sum of both by running the following 4 lines in a shell wherever you have the files downloaded: cat < Morning All I'm working through the tutorial and running / saving work that I wish to keep and build on, most times I can save and (re)import later with no difference to when typed in console or editor and run with F5 (which saves before it can run) But sometimes saved work (albeit small) when imported does not work any longer I assume I have missed something, any pointers to what/how/why please From bschollnick at schollnick.net Fri May 19 06:41:58 2023 From: bschollnick at schollnick.net (Benjamin Schollnick) Date: Fri, 19 May 2023 06:41:58 -0400 Subject: txtorcon 23.5.0 In-Reply-To: <6pA9M.276484$qjm2.29867@fx09.iad> References: <6pA9M.276484$qjm2.29867@fx09.iad> Message-ID: Meejah, Sorry, but, would you please consider adding a short description to this of what txtorcon is. It?s great that your announcing the update, and highlighting the changes?if I used it, I?d be upgrading it. But I have absolutely no idea why I would want to investigate using it, because there is no description of the package. Well, that?s not 100% true. From my knowledge of twisted, I know it?s network based, and that?s it. I can?t tell if it?s a server, or client application. Even just simply adding your 10,000 feet summary: txtorcon is an implementation of the control-spec for Tor using the Twisted networking library for Python . would have been extremely helpful. I hope you will take this as the creative criticism that I am offering it as. - Benjamin > On May 18, 2023, at 9:37 PM, meejah at meejah.ca wrote: > > > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA512 > > I'm happy to announce txtorcon 23.5.0 with the following changes: > > * twisted.web.client.Agent instances now use the same HTTPS policy > by default as twisted.web.client.Agent. It is possible to > override this policy with the tls_context_factory= argument, the > equivalent to Agent's contextFactory= > (Thanks to Itamar Turner-Trauring) > * Added support + testing for Python 3.11. > * No more ipaddress dependency > > You can download the release from PyPI or GitHub (or of > course "pip install txtorcon"): > > https://pypi.python.org/pypi/txtorcon/23.5.0 > https://github.com/meejah/txtorcon/releases/tag/v23.5.0 > > Releases are also available from the hidden service: > > http://fjblvrw2jrxnhtg67qpbzi45r7ofojaoo3orzykesly2j3c2m3htapid.onion/txtorcon-23.5.0.tar.gz > http://fjblvrw2jrxnhtg67qpbzi45r7ofojaoo3orzykesly2j3c2m3htapid.onion/txtorcon-23.5.0.tar.gz.asc > > You can verify the sha256sum of both by running the following 4 lines > in a shell wherever you have the files downloaded: > > cat < 93fd80a9dd505f698d0864fe93db8b6a9c1144b5feb91530820b70ed8982651c dist/txtorcon-23.5.0.tar.gz > 987f0a91184f98cc3f0a7eccaa42f5054063744d6ac15e325cfa666403214208 dist/txtorcon-23.5.0-py3-none-any.whl > EOF > > thanks, > meejah > -----BEGIN PGP SIGNATURE----- > > iQFFBAEBCgAvFiEEnVor1WiOy4id680/wmAoAxKAaacFAmRm0DoRHG1lZWphaEBt > ZWVqYWguY2EACgkQwmAoAxKAaae/+wgAw3gAm65npc7+yMdGFixNmCd+RUXorJq9 > Hy76hK3BWdtNIA6TZF20QFYs3CX5Vepa0vCJOK1N40fYgxoZTb1/828Zp6Zq2+Gn > piJGvQ0Z1S95ww7lwSV77o67Xf7PozhLR+k7DaOdY8ugvLb/0Rdp15BykF5DWIo8 > PRgqB8uZ418ebmDLLrYtqYTdlcUMxFTji4CHXc4N55/2hVHiFiuFt59os6kJ3iG1 > u90lmQH8vbDyVF7N6tpgEAdWeb7OdgDbtzhVBdBWHrPg+vDO+UL7WZU8ZjDAcdEr > YzzmK3fIiCH7ngG2E/VIebiJfrjAA9G4eZXltIm7VcWh5css9MXY1Q== > =TeQp > -----END PGP SIGNATURE----- > -- > https://mail.python.org/mailman/listinfo/python-list From learn2program at gmail.com Fri May 19 07:25:01 2023 From: learn2program at gmail.com (Alan Gauld) Date: Fri, 19 May 2023 12:25:01 +0100 Subject: Silly (maybe) question re imported module(s) In-Reply-To: <64671ABC.387.1AA74D@RealGrizzlyAdams.vivaldi.net> References: <64671ABC.387.1AA74D@RealGrizzlyAdams.vivaldi.net> Message-ID: <13f3d040-2bc0-ae68-1263-0ac3b6b29c31@yahoo.co.uk> On 19/05/2023 07:44, Grizzy Adams via Python-list wrote: > when typed in console or editor and run with F5 (which saves before it can run) > > But sometimes saved work (albeit small) when imported does not work any longer Looks like you are using IDLE? If so, it's possible that in the original case you had some values set from a previous run that were picked up but when you reimport later those values are missing. It would help if you can post any error messages since they should give clues(like name errors for example). Also describe how you are "importing" the modules. are you typing >>> import mymodule at the interactive prompt or are you using the File->Open menu to load them into the editor? (It sounds like the latter) -- 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 barry at barrys-emacs.org Fri May 19 07:25:05 2023 From: barry at barrys-emacs.org (Barry Scott) Date: Fri, 19 May 2023 12:25:05 +0100 Subject: Silly (maybe) question re imported module(s) In-Reply-To: <64671ABC.387.1AA74D@RealGrizzlyAdams.vivaldi.net> References: <64671ABC.387.1AA74D@RealGrizzlyAdams.vivaldi.net> Message-ID: <05DA5F74-8B3B-4F98-944E-DBC95F838F98@barrys-emacs.org> > On 19 May 2023, at 07:44, Grizzy Adams via Python-list wrote: > > Morning All > > I'm working through the tutorial and running / saving work that I wish to keep > and build on, most times I can save and (re)import later with no difference to > when typed in console or editor and run with F5 (which saves before it can run) > > > But sometimes saved work (albeit small) when imported does not work any longer > > I assume I have missed something, any pointers to what/how/why please reimport is not 100% reliable, in simple cases it will work, but as your code gets more complex it can break. I rarely use reimport. Usually just exit python and start again. If you are working on scripts then just run them from the Terminal will work well with any need to use reimport. Barry > > > > > -- > https://mail.python.org/mailman/listinfo/python-list > From tdldev at gmail.com Fri May 19 08:18:20 2023 From: tdldev at gmail.com (Jack Dangler) Date: Fri, 19 May 2023 08:18:20 -0400 Subject: txtorcon 23.5.0 In-Reply-To: References: <6pA9M.276484$qjm2.29867@fx09.iad> Message-ID: On 5/19/23 06:41, Benjamin Schollnick wrote: > Meejah, > > Sorry, but, would you please consider adding a short description to this of what txtorcon is. > It?s great that your announcing the update, and highlighting the changes?if I used it, I?d be upgrading it. > > But I have absolutely no idea why I would want to investigate using it, because there is no description of the package. > > Well, that?s not 100% true. From my knowledge of twisted, I know it?s network based, and that?s it. I can?t tell if it?s a server, or client application. > > Even just simply adding your 10,000 feet summary: > > txtorcon is an implementation of the control-spec for Tor using the Twisted networking library for Python . > > would have been extremely helpful. > > I hope you will take this as the creative criticism that I am offering it as. > > - Benjamin > > >> On May 18, 2023, at 9:37 PM, meejah at meejah.ca wrote: >> >> > I'm happy to announce txtorcon 23.5.0 with the following changes: > > ?* twisted.web.client.Agent instances now use the same HTTPS policy > ?? by default as twisted.web.client.Agent.? It is possible to > ?? override this policy with the tls_context_factory= argument, the > ?? equivalent to Agent's contextFactory= > ?? (Thanks to Itamar Turner-Trauring) > ?* Added support + testing for Python 3.11. > ?* No more ipaddress dependency > > You can download the release from PyPI or GitHub (or of > course "pip install txtorcon"): > > https://pypi.python.org/pypi/txtorcon/23.5.0 > https://github.com/meejah/txtorcon/releases/tag/v23.5.0 > > Releases are also available from the hidden service: > > http://fjblvrw2jrxnhtg67qpbzi45r7ofojaoo3orzykesly2j3c2m3htapid.onion/txtorcon-23.5.0.tar.gz > http://fjblvrw2jrxnhtg67qpbzi45r7ofojaoo3orzykesly2j3c2m3htapid.onion/txtorcon-23.5.0.tar.gz.asc > > You can verify the sha256sum of both by running the following 4 lines > in a shell wherever you have the files downloaded: > > cat < 93fd80a9dd505f698d0864fe93db8b6a9c1144b5feb91530820b70ed8982651c > dist/txtorcon-23.5.0.tar.gz > 987f0a91184f98cc3f0a7eccaa42f5054063744d6ac15e325cfa666403214208 > dist/txtorcon-23.5.0-py3-none-any.whl > EOF > > thanks, > meejah >> -- >> https://mail.python.org/mailman/listinfo/python-list > *Top-posting? Really? Actually, a very cursory look through the intarweb would have yielded this - https://txtorcon.readthedocs.io/en/latest/introduction.html as well as this - https://github.com/meejah/txtorcon While there are one or two graphical package managers (yumex and yumex-dnf that I know of), have a go at the cli manager(s) that may live on your distro and see if you can get pkg info about it. If you're not sure which one(s) you have, try these - Yum, Dnf, Rpm,Apt, Apt-Get, Deb, pacman, dpkg, and zypper for starters. *dpkg is my go-to pkgmgr of choice... Also, the names of many linux-centric utility plugins, extensions, and other goodies, while seemingly cryptic, are usually a prominent clue as to what the package is used for. The world of *NIX has never been for the faint of heart, but there are lots of very helping hands in its communities... :) Jack From RealGrizzlyAdams at vivaldi.net Fri May 19 08:36:07 2023 From: RealGrizzlyAdams at vivaldi.net (Grizzy Adams) Date: Fri, 19 May 2023 13:36:07 +0100 Subject: Silly (maybe) question re imported module(s) In-Reply-To: <05DA5F74-8B3B-4F98-944E-DBC95F838F98@barrys-emacs.org> References: <64671ABC.387.1AA74D@RealGrizzlyAdams.vivaldi.net>, <05DA5F74-8B3B-4F98-944E-DBC95F838F98@barrys-emacs.org> Message-ID: <64676D37.22671.7D26B2@RealGrizzlyAdams.vivaldi.net> Friday, May 19, 2023 at 12:25, Barry Scott wrote: Re: Silly (maybe) question re impor (at least in part) > > >> On 19 May 2023, at 07:44, Grizzy Adams via Python-list wrote: >> >> Morning All >> >> I'm working through the tutorial and running / saving work that I wish to keep >> and build on, most times I can save and (re)import later with no difference to >> when typed in console or editor and run with F5 (which saves before it can run) >> >> But sometimes saved work (albeit small) when imported does not work any longer >> I assume I have missed something, any pointers to what/how/why please >reimport is not 100% reliable, in simple cases it will work, but as your >code gets more complex it can break. at the moment my code is very minimal, one saved piece is a nice one-liner that I kept because I wanted to remember syntax and how easy/elegant "some" things are in python, but if I import it it fails >I rarely use reimport. Usually just exit python and start again. I may have confused this I use import to get my saved work, the "re" was to shoe it had been saved by the editor >If you are working on scripts then just run them from the Terminal >will work well with any need to use reimport. From bschollnick at schollnick.net Fri May 19 08:42:43 2023 From: bschollnick at schollnick.net (Benjamin Schollnick) Date: Fri, 19 May 2023 08:42:43 -0400 Subject: txtorcon 23.5.0 In-Reply-To: References: <6pA9M.276484$qjm2.29867@fx09.iad> Message-ID: <824A41F4-2A68-4A6D-8227-B65C3DA01C31@schollnick.net> > *Top-posting? Really? In that case, yes, because the conversion did not depend on what was originally said. Unlike this conversation. > Actually, a very cursory look through the intarweb would have yielded this - And that?s the point, if you want to me to consider your package, I should have some idea that it?s worth me investing more time into seeing if it can help me. As I mentioned simply stating that it was a ?Tor Control management API? would have been enough for me to say ?That?s not helpful to me?. On the other hand if it said ?Django management API/Tool?, I would have gone to the git repository and investigated. Effectively, posting a release notification is an advertisement for the package, as well as a notice saying ?Here?s some updates?. When done correctly, it can bring more people to use your package / software? > While there are one or two graphical package managers (yumex and yumex-dnf that I know of), have a go at the cli manager(s) that may live on your distro and see if you can get pkg info about it. If you're not sure which one(s) you have, try these - Yum, Dnf, Rpm,Apt, Apt-Get, Deb, pacman, dpkg, and zypper for starters. *dpkg is my go-to pkgmgr of choice... > > Also, the names of many linux-centric utility plugins, extensions, and other goodies, while seemingly cryptic, are usually a prominent clue as to what the package is used for. The world of *NIX has never been for the faint of heart, but there are lots of very helping hands in its communities... :) This has nothing to do with package managers, this has to do with ?Why should I use this package? or ?Should I use this package / software?. If the release notes are being send to people that don?t already have the package then it?s worth the couple of sentences or a short paragraph to allow someone that is unfamiliar with the package to be able to see if they should investigate the package. Cryptic names maybe cute, but if they are not descriptive, then they are not really that helpful other than being unique. - Benjamin From tdldev at gmail.com Fri May 19 09:24:17 2023 From: tdldev at gmail.com (Jack Dangler) Date: Fri, 19 May 2023 09:24:17 -0400 Subject: Tkinter (related)~ In-Reply-To: <6466ccba.920a0220.afe81.0bd0@mx.google.com> References: <13a1c77e-83b2-55ea-4c94-7636c3bd8d70@gmail.com> <6466ccba.920a0220.afe81.0bd0@mx.google.com> Message-ID: <9c6128bf-97e8-308d-9579-93a7552a2a1d@gmail.com> On 5/18/23 21:11, Grant Edwards wrote: > On 2023-05-19, Cameron Simpson wrote: >> On 18May2023 12:06, Jack Dangler wrote: >>> I thought the OP of the tkinter thread currently running may have >>> needed to install the tkinter package (since I had the same missing >>> component error message), so I tried to install the package on to my >>> Ubu laptop - >>> >>> pip install tkinter >>> Defaulting to user installation because normal site-packages is not >>> writeable >>> ERROR: Could not find a version that satisfies the requirement tkinter >>> (from versions: none) >>> ERROR: No matching distribution found for tkinter >>> >>> Is there an alternate path to installing this? >> Usually tkinter ships with Python because it is part of the stdlib. >> >> On some platforms eg Ubuntu Linux the stdlib doesn't come in completely >> unless you ask - a lot of stdlib packages are apt things you need to ask >> for. On my Ubunut here tkinter comes from python3-tk. So: >> >> $ sudo apt-get install python3-tk > And in general, on Linux systems, you'll be better off in the long run > if you use the distro's package manager to install Python packages > instead of using pip. If there is no distro package, you're usually > also better off using 'pip install --user' so that pip isn't messing > about with directories that are normally managed by the distro's > package manager. > > When I do have to resort to using pip in install something, I always > do a --dry-run first and make a note of any dependancies that pip is > going to try to install -- so I can install those using the package > manager if possible. > > -- > Grant > Grant Great suggestion! I didn't know that --dry-run was available... I'll have to look at that arg... Jack From tdldev at gmail.com Fri May 19 09:30:16 2023 From: tdldev at gmail.com (Jack Dangler) Date: Fri, 19 May 2023 09:30:16 -0400 Subject: txtorcon 23.5.0 In-Reply-To: <824A41F4-2A68-4A6D-8227-B65C3DA01C31@schollnick.net> References: <6pA9M.276484$qjm2.29867@fx09.iad> <824A41F4-2A68-4A6D-8227-B65C3DA01C31@schollnick.net> Message-ID: On 5/19/23 08:42, Benjamin Schollnick wrote: > >> *Top-posting? Really? > > In that case, yes, because the conversion did not depend on what was > originally said. ?Unlike this conversation. > >> Actually, a very cursory look through the intarweb would have yielded >> this - > > And that?s the point, if you want to me to consider your package, I > should have some idea that it?s worth me investing more time into > seeing if it can help me. ?As I mentioned simply stating that it was a > ?Tor Control management API? would have been enough for me to say > ?That?s not helpful to me?. ?On the other hand if it said ?Django > management API/Tool?, I would have gone to the git repository and > investigated. > > Effectively, posting a release notification is an *advertisement for > the package*, as well as a notice saying ?*Here?s some updates?.* > * > * > When done correctly, it can bring more people to use your package / > software? > >> While there are one or two graphical package managers (yumex and >> yumex-dnf that I know of), have a go at the cli manager(s) that may >> live on your distro and see if you can get pkg info about it. If >> you're not sure which one(s) you have, try these - Yum, Dnf, Rpm,Apt, >> Apt-Get, Deb, pacman, dpkg, and zypper for starters. *dpkg is my >> go-to pkgmgr of choice... >> >> Also, the names of many linux-centric utility plugins, extensions, >> and other goodies, while seemingly cryptic, are usually a prominent >> clue as to what the package is used for. The world of *NIX has never >> been for the faint of heart, but there are lots of very helping hands >> in its communities... :) > > This has nothing to do with package managers, this has to do with ?Why > should I use this package? or ?Should I use this package / software?. > ?If the release notes are being send to people that don?t already have > the package then it?s worth the couple of sentences or a short > paragraph to allow someone that is unfamiliar with the package to be > able to see if they should investigate the package. > > Cryptic names maybe cute, but if they are not descriptive, then they > are not really that helpful other than being unique. > > - Benjamin > Yeah - um - I get the impression that there is so much going on that either I'm not qualified to respond to it, or I'd have to charge by the hour to unravel it, I'm just gonna leave this right here... From learn2program at gmail.com Fri May 19 13:18:35 2023 From: learn2program at gmail.com (Alan Gauld) Date: Fri, 19 May 2023 18:18:35 +0100 Subject: Silly (maybe) question re imported module(s) In-Reply-To: <64676D37.5321.7D27AC@RealGrizzlyAdams.vivaldi.net> References: <64671ABC.387.1AA74D@RealGrizzlyAdams.vivaldi.net> <13f3d040-2bc0-ae68-1263-0ac3b6b29c31@yahoo.co.uk> <64676D37.5321.7D27AC@RealGrizzlyAdams.vivaldi.net> Message-ID: <80964874-2c69-9969-1699-35b57e75ab7b@gmail.com> On 19/05/2023 13:36, Grizzy Adams wrote: >> Looks like you are using IDLE? > > Yes > > > From consol > >>>> import cube >>>> cubes > Traceback (most recent call last): > File "", line 1, in > cubes > NameError: name 'cubes' is not defined You imported cube but tried to use cubes. I'm guessing cubes is defined inside cube so you would need cube.cubes > File->Open mymodule.module into the editor, then F5 to run all is well > >>>> > ================ RESTART: D:\Shades\Tools\Python\Temp\cube.py ================ >>>> cubes > [0, 1, 8, 27, 64, 125, 216, 343, 512, 729] cubes looks like it should be a function but in that case there should be parens after it. So I'm not sure how that is working! I'd expect that you need to do: import cube cube.cubes() -- 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 fungus at amongus.com Fri May 19 15:18:19 2023 From: fungus at amongus.com (Retrograde) Date: Fri, 19 May 2023 15:18:19 -0400 Subject: What to use instead of nntplib? References: <6462a009.050a0220.60724.3315@mx.google.com> <469aa006-40d4-38c8-5776-fe0f9e908cf1@yahoo.co.uk> <64634F11.6369.1A7139@RealGrizzlyAdams.vivaldi.net> <744cjj-9dqi3.ln1@esprimo.zbmc.eu> <64639ddd.020a0220.4bd44.83fd@mx.google.com> Message-ID: <20230519151819.5e78facbbffa4ddb34833c49@amongus.com> > > Yes, me for one, a good newsreader is really a wonderful way to manage > > technical 'lists' like this one. > > IMO, there's nothing better. Newsreaders were designed from the > beginning to deal with the sort of traffic and usage patterns seen in > mailing lists. Using an MUA (even combined with something like > procmail) and folders/labels is just a pale imitation of a good > newsreader. > > > Usenet news is still very much alive though a minority interest now > > I suspect. > > This list's decision to stop accepting postings via news.gmane.io is > what prompted me to write my own "inews" application in Python that > uses SMTP for some groups and NNTP for others when I "post" via slrn. > > I probably use NNTP more to access mailing lists via gmane than I use > it for accessing the "real" Usenet groups. > > NNTP is not just for Usenet... I asked this question in February and got the same response. But on news.software.readers 16 May, Ted Heise posted a useful perl script. I'm starting to think I'll move to Perl for Usenet posting; I have yet to find a Python solution easy enough for this non-technical user. From learn2program at gmail.com Fri May 19 18:49:42 2023 From: learn2program at gmail.com (Alan Gauld) Date: Fri, 19 May 2023 23:49:42 +0100 Subject: Silly (maybe) question re imported module(s) In-Reply-To: <6467C40A.23592.5DA17B@RealGrizzlyAdams.vivaldi.net> References: <64671ABC.387.1AA74D@RealGrizzlyAdams.vivaldi.net> <64676D37.5321.7D27AC@RealGrizzlyAdams.vivaldi.net> <80964874-2c69-9969-1699-35b57e75ab7b@gmail.com> <6467C40A.23592.5DA17B@RealGrizzlyAdams.vivaldi.net> Message-ID: On 19/05/2023 19:46, Grizzy Adams wrote: > Tried that > ================ RESTART: D:\Shades\Tools\Python\Temp\cube.py ================ >>>> cubes() > Traceback (most recent call last): > File "", line 1, in > cubes() > TypeError: 'list' object is not callable Ah, now I understand. cubes is a literal list defined in the module. > But that was spot on, thanks > >>>> import cube >>>> cube.cubes > [0, 1, 8, 27, 64, 125, 216, 343, 512, 729] Glad to help. -- 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 alexjando2007 at gmail.com Sat May 20 13:54:59 2023 From: alexjando2007 at gmail.com (Alex Jando) Date: Sat, 20 May 2023 10:54:59 -0700 (PDT) Subject: Addition of a .= operator Message-ID: <435bae66-e0b8-49da-bb39-10606492b59dn@googlegroups.com> I have many times had situations where I had a variable of a certain type, all I cared about it was one of it's methods. For example: ------------------------------------------------------------ import hashlib hash = hashlib.sha256(b'word') hash = hash.hexdigest() ------------------------------------------------------------ import enum class Number(enum.Enum): One: int = 1 Two: int = 2 Three: int = 3 num = Number.One num = num.value ------------------------------------------------------------ Now to be fair, in the two situations above, I could just access the method right as I declare the object, however, sometimes when passing values into functions, it's a lot messier to do that. So what I'm suggesting is something like this: ------------------------------------------------------------ import hashlib hash = hashlib.sha256(b'word') hash.=hexdigest() ------------------------------------------------------------ import enum class Number(enum.Enum): One: int = 1 Two: int = 2 Three: int = 3 num = Number.One num.=value ------------------------------------------------------------ From PythonList at DancesWithMice.info Sat May 20 14:11:02 2023 From: PythonList at DancesWithMice.info (dn) Date: Sun, 21 May 2023 06:11:02 +1200 Subject: Addition of a .= operator In-Reply-To: <435bae66-e0b8-49da-bb39-10606492b59dn@googlegroups.com> References: <435bae66-e0b8-49da-bb39-10606492b59dn@googlegroups.com> Message-ID: On 21/05/2023 05.54, Alex Jando wrote: > I have many times had situations where I had a variable of a certain type, all I cared about it was one of it's methods. > > For example: > > ------------------------------------------------------------ > import hashlib > hash = hashlib.sha256(b'word') > hash = hash.hexdigest() > ------------------------------------------------------------ > import enum > class Number(enum.Enum): > One: int = 1 > Two: int = 2 > Three: int = 3 > num = Number.One > num = num.value > ------------------------------------------------------------ > > Now to be fair, in the two situations above, I could just access the method right as I declare the object, however, sometimes when passing values into functions, it's a lot messier to do that. > > So what I'm suggesting is something like this: > > ------------------------------------------------------------ > import hashlib > hash = hashlib.sha256(b'word') > hash.=hexdigest() > ------------------------------------------------------------ > import enum > class Number(enum.Enum): > One: int = 1 > Two: int = 2 > Three: int = 3 > num = Number.One > num.=value > ------------------------------------------------------------ A custom-class wrapper? Even, a decorator-able function? -- Regards, =dn From 2QdxY4RzWzUUiLuE at potatochowder.com Sat May 20 14:48:34 2023 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Sat, 20 May 2023 14:48:34 -0400 Subject: Addition of a .= operator In-Reply-To: References: <435bae66-e0b8-49da-bb39-10606492b59dn@googlegroups.com> Message-ID: On 2023-05-21 at 06:11:02 +1200, dn via Python-list wrote: > On 21/05/2023 05.54, Alex Jando wrote: > > I have many times had situations where I had a variable of a certain type, all I cared about it was one of it's methods. > > > > For example: > > > > ------------------------------------------------------------ > > import hashlib > > hash = hashlib.sha256(b'word') > > hash = hash.hexdigest() > > ------------------------------------------------------------ > > import enum > > class Number(enum.Enum): > > One: int = 1 > > Two: int = 2 > > Three: int = 3 > > num = Number.One > > num = num.value > > ------------------------------------------------------------ > > > > Now to be fair, in the two situations above, I could just access the method right as I declare the object, however, sometimes when passing values into functions, it's a lot messier to do that. Can you give an example, preferably one from an actual program, that shows the mess? Is it More Messier? than the difference between the following examples? # example 1 hash = hashlib.sha256(b'word') f(hash.hexdigest()) # call f with hash's hexdigest # example 2 hash = hashlib.sha256(b'word') hash = hash.hexdigest() # extract hash's hexdigest f(hash) # call f with hash's hexdigest Can you also show what your code would look like with a .= operator? > > So what I'm suggesting is something like this: > > > > ------------------------------------------------------------ > > import hashlib > > hash = hashlib.sha256(b'word') > > hash.=hexdigest() > > ------------------------------------------------------------ > > import enum > > class Number(enum.Enum): > > One: int = 1 > > Two: int = 2 > > Three: int = 3 > > num = Number.One > > num.=value > > ------------------------------------------------------------ > > A custom-class wrapper? > Even, a decorator-able function? From avi.e.gross at gmail.com Sat May 20 15:52:54 2023 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Sat, 20 May 2023 15:52:54 -0400 Subject: Addition of a .= operator In-Reply-To: References: <435bae66-e0b8-49da-bb39-10606492b59dn@googlegroups.com> Message-ID: <000701d98b54$ab368150$01a383f0$@gmail.com> I would suggest thinking carefully about ramifications as well as any benefits of adding some or .=operator. It sounds substantially different than the whole slew of +=, *= and so on types of operators. The goal some would say of those is to either allow the interpreter optimize by not evaluating twice as in x = x + 1 or python extensions of the dunder type like __iadd__() that allow you to control what exactly is done and which sometimes make a += b do things a bit different than a= a+b. So what would a __i_invoke_method__() function look like? It seems you want the command to sort of replace Object = Object.method(args) But for any method whatsoever. But Python objects can have methods all over the place as they may be subclasses that inherit methods, or may implement an abstract method or use multiple inheritance. All that searching happens in the current way, so if Object.method(args)) Works as expected, would your new method be just syntactic sugar, or would it look for a dunder method that may have no idea initially what you want? Just curious. Is there an alternative way you could get the functionality without using the same way that is used for a very different circumstance? -----Original Message----- From: Python-list On Behalf Of 2QdxY4RzWzUUiLuE at potatochowder.com Sent: Saturday, May 20, 2023 2:49 PM To: python-list at python.org Subject: Re: Addition of a .= operator On 2023-05-21 at 06:11:02 +1200, dn via Python-list wrote: > On 21/05/2023 05.54, Alex Jando wrote: > > I have many times had situations where I had a variable of a certain type, all I cared about it was one of it's methods. > > > > For example: > > > > ------------------------------------------------------------ > > import hashlib > > hash = hashlib.sha256(b'word') > > hash = hash.hexdigest() > > ------------------------------------------------------------ > > import enum > > class Number(enum.Enum): > > One: int = 1 > > Two: int = 2 > > Three: int = 3 > > num = Number.One > > num = num.value > > ------------------------------------------------------------ > > > > Now to be fair, in the two situations above, I could just access the method right as I declare the object, however, sometimes when passing values into functions, it's a lot messier to do that. Can you give an example, preferably one from an actual program, that shows the mess? Is it More Messier? than the difference between the following examples? # example 1 hash = hashlib.sha256(b'word') f(hash.hexdigest()) # call f with hash's hexdigest # example 2 hash = hashlib.sha256(b'word') hash = hash.hexdigest() # extract hash's hexdigest f(hash) # call f with hash's hexdigest Can you also show what your code would look like with a .= operator? > > So what I'm suggesting is something like this: > > > > ------------------------------------------------------------ > > import hashlib > > hash = hashlib.sha256(b'word') > > hash.=hexdigest() > > ------------------------------------------------------------ > > import enum > > class Number(enum.Enum): > > One: int = 1 > > Two: int = 2 > > Three: int = 3 > > num = Number.One > > num.=value > > ------------------------------------------------------------ > > A custom-class wrapper? > Even, a decorator-able function? -- https://mail.python.org/mailman/listinfo/python-list From hjp-python at hjp.at Sat May 20 16:15:24 2023 From: hjp-python at hjp.at (Peter J. Holzer) Date: Sat, 20 May 2023 22:15:24 +0200 Subject: Addition of a .= operator In-Reply-To: <435bae66-e0b8-49da-bb39-10606492b59dn@googlegroups.com> References: <435bae66-e0b8-49da-bb39-10606492b59dn@googlegroups.com> Message-ID: <20230520201524.5bvzkqtjhdwq3syg@hjp.at> On 2023-05-20 10:54:59 -0700, Alex Jando wrote: > I have many times had situations where I had a variable of a certain > type, all I cared about it was one of it's methods. > > For example: > > ------------------------------------------------------------ > hash = hash.hexdigest() > ------------------------------------------------------------ > num = num.value > ------------------------------------------------------------ > > So what I'm suggesting is something like this: > > ------------------------------------------------------------ > hash.=hexdigest() > ------------------------------------------------------------ > num.=value > ------------------------------------------------------------ I actually needed to read those twice to get their meaning. I think hash .= hexdigest() num .= value would have been clearer (yes, I nag my colleagues about white-space, too). Do you have any examples (preferably from real code) where you don't assign to a simple variable? I feel that x += 1 isn't much of an improvement over x = x + 1 but self.data[line+len(chars)-1] += after is definitely an improvement over self.data[line+len(chars)-1] + self.data[line+len(chars)-1] + after 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 mats at wichmann.us Sat May 20 17:05:56 2023 From: mats at wichmann.us (Mats Wichmann) Date: Sat, 20 May 2023 15:05:56 -0600 Subject: Error installing packages or upgrading pip In-Reply-To: References: Message-ID: On 5/18/23 04:30, Test Only wrote: > Hi there, I hope you are in a great health > > I am having a problem with python even though I uninstall and reinstall it > again multiple times Ummm... there's usually not a great reason to do that. I know it's the traditional "Windows Way" of the past, but usually looking for actual solutions first is better than "reinstall because it might be corrupted". To put it in snarky terms: reach for the sledgehammer only once you know the use of a sledge is warranted. Have you tried searching for this through a search engine? A really quick try shows several hits, including some StackOverflow articles. There's no way for us to judge if any of those scenarios actually would apply to your case, so suggesting you take a look first. > the error I get when I try to upgrade or install a package for example > > pip install requests > > I get this error which I could not find a solution for > > > > pip install requests > Requirement already satisfied: requests in > c:\users\uly\appdata\local\programs\python\python310\lib\site-packages\requests-2.30.0-py3.10.egg > (2.30.0) > WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, > status=None)) after connection broken by 'ProtocolError('Connection > aborted.', FileNotFoundError(2, 'No such file or directory'))': > /simple/charset-normalizer/ > WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, > status=None)) after connection broken by 'ProtocolError('Connection > aborted.', FileNotFoundError(2, 'No such file or directory'))': > /simple/charset-normalizer/ > WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, > status=None)) after connection broken by 'ProtocolError('Connection > aborted.', FileNotFoundError(2, 'No such file or directory'))': > /simple/charset-normalizer/ > WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, > status=None)) after connection broken by 'ProtocolError('Connection > aborted.', FileNotFoundError(2, 'No such file or directory'))': > /simple/charset-normalizer/ > WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, > status=None)) after connection broken by 'ProtocolError('Connection > aborted.', FileNotFoundError(2, 'No such file or directory'))': > /simple/charset-normalizer/ > WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, > status=None)) after connection broken by 'ProtocolError('Connection > aborted.', FileNotFoundError(2, 'No such file or directory'))': > /simple/requests/ > WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, > status=None)) after connection broken by 'ProtocolError('Connection > aborted.', FileNotFoundError(2, 'No such file or directory'))': > /simple/requests/ > WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, > status=None)) after connection broken by 'ProtocolError('Connection > aborted.', FileNotFoundError(2, 'No such file or directory'))': > /simple/requests/ > WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, > status=None)) after connection broken by 'ProtocolError('Connection > aborted.', FileNotFoundError(2, 'No such file or directory'))': > /simple/requests/ > WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, > status=None)) after connection broken by 'ProtocolError('Connection > aborted.', FileNotFoundError(2, 'No such file or directory'))': > /simple/requests/ > ERROR: Could not find a version that satisfies the requirement > charset_normalizer<4,>=2 (from requests) (from versions: none) > ERROR: No matching distribution found for charset_normalizer<4,>=2 > WARNING: There was an error checking the latest version of pip. From Richard at Damon-Family.org Sat May 20 17:18:43 2023 From: Richard at Damon-Family.org (Richard Damon) Date: Sat, 20 May 2023 17:18:43 -0400 Subject: Addition of a .= operator In-Reply-To: <20230520201524.5bvzkqtjhdwq3syg@hjp.at> References: <435bae66-e0b8-49da-bb39-10606492b59dn@googlegroups.com> <20230520201524.5bvzkqtjhdwq3syg@hjp.at> Message-ID: On 5/20/23 4:15 PM, Peter J. Holzer wrote: > On 2023-05-20 10:54:59 -0700, Alex Jando wrote: >> I have many times had situations where I had a variable of a certain >> type, all I cared about it was one of it's methods. >> >> For example: >> >> ------------------------------------------------------------ >> hash = hash.hexdigest() >> ------------------------------------------------------------ >> num = num.value >> ------------------------------------------------------------ >> >> So what I'm suggesting is something like this: >> >> ------------------------------------------------------------ >> hash.=hexdigest() >> ------------------------------------------------------------ >> num.=value >> ------------------------------------------------------------ > I actually needed to read those twice to get their meaning. I think > > hash .= hexdigest() > num .= value > > would have been clearer (yes, I nag my colleagues about white-space, > too). > > Do you have any examples (preferably from real code) where you don't > assign to a simple variable? I feel that > x += 1 > isn't much of an improvement over > x = x + 1 > but > self.data[line+len(chars)-1] += after > is definitely an improvement over > self.data[line+len(chars)-1] + self.data[line+len(chars)-1] + after > > hp > > For immutable types, it is just syntactic sugar, but for mutable type there is an important difference x = [] y = x x += [1] changes the list named by y, but x = [] y = x x = x + [] does not. The key is that if a type actually implements the inplace operator, then using the op= version doesn't bind the name to a new object but mutates the object to a new value. This just can't happen (as far as I can figure) for .= unless the object is defining something weird for the inplace version of the operation, which is probably best to not actually allow. -- Richard Damon From greg.ewing at canterbury.ac.nz Sat May 20 20:11:35 2023 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Sun, 21 May 2023 12:11:35 +1200 Subject: Addition of a .= operator In-Reply-To: <435bae66-e0b8-49da-bb39-10606492b59dn@googlegroups.com> References: <435bae66-e0b8-49da-bb39-10606492b59dn@googlegroups.com> Message-ID: On 21/05/23 5:54 am, Alex Jando wrote: > hash.=hexdigest() That would be a very strange and unprecedented syntax that munges together an attribute lookup and a call. Keep in mind that a method call in Python is actually two separate things: y = x.m() is equivalent to f = x.m y = f() But it would not be possible to break down your .= syntax in that way. Another oddity is that these are equivalent: x += y x += (y) i.e. the RHS is evaluated as usual before doing the +=. But these would not be equivalent: hash .= hexdigest() hash .= (hexdigest()) In fact the latter would probably have to be disallowed, as it's not at all clear what it should mean. -- Greg From greg.ewing at canterbury.ac.nz Sat May 20 20:23:30 2023 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Sun, 21 May 2023 12:23:30 +1200 Subject: Addition of a .= operator In-Reply-To: References: <435bae66-e0b8-49da-bb39-10606492b59dn@googlegroups.com> <20230520201524.5bvzkqtjhdwq3syg@hjp.at> Message-ID: On 21/05/23 9:18 am, Richard Damon wrote: > This just can't happen (as far as I can figure) for .= unless the object > is defining something weird for the inplace version of the operation, Indeed. There are clear use cases for overriding +=, but it's hard to think of one for this. So it would just be syntactic sugar, which is harder to justify. -- Greg From guenther.sohler at gmail.com Sun May 21 17:40:10 2023 From: guenther.sohler at gmail.com (Guenther Sohler) Date: Sun, 21 May 2023 23:40:10 +0200 Subject: Create Statically linked python library Message-ID: Right now my application links python dynamically. That means ldd will show something like libpython3.11.so.1.0 => /lib64/libpython3.11.so.1.0 (0x00007fd63c600000) but i dont like this dependency. ii want to link in python statically. I'd like to get a file like libpython3.11.a or similar. For that I have found https://wiki.python.org/moin/BuildStatically It describes how to compile python interpreter statically and it only contains view libs But I;d like to get a libpython3.11.a instead. How can i get this ? Thank you From cl at isbd.net Sat May 20 15:53:57 2023 From: cl at isbd.net (Chris Green) Date: Sat, 20 May 2023 20:53:57 +0100 Subject: Is there a Python module to parse a date like the 'date' command in Linux? Message-ID: I'm converting a bash script to python as it has become rather clumsy in bash. However I have hit a problem with converting dates, the bash script has:- dat=$(date --date "$1" +"%Y/%m/%d") and this will accept almost anything reasonably sensible that can be interpreted as a date, in particular it accepts things like "tomorrow", "yesterday" and "next thursday". Is there anything similar in Python or would I be better off simply using os.system() to run date from the python program? -- Chris Green ? From fungus at amongus.com Sun May 21 07:10:44 2023 From: fungus at amongus.com (Retrograde) Date: Sun, 21 May 2023 07:10:44 -0400 Subject: What to use instead of nntplib? References: <469aa006-40d4-38c8-5776-fe0f9e908cf1@yahoo.co.uk> <960340a9-2f55-9e48-4bb3-b39352387935@gmail.com> <6463862f.020a0220.21ee1.48db@mx.google.com> Message-ID: <20230521071044.6879162343f314b305574d14@amongus.com> > >> See PEP 594: https://peps.python.org/pep-0594/ > > > > Thanks Cameron. > > A scary list; I must have a dozen projects from the late 90s still > > live that are using many of these! I'm glad I'm retired and won't > > be the one who has to fix 'em :-) > > It has been pointed out to me that Perl still has a supported NNTP > library. That stung. However, it's a CPAN module, which is more > equivalent to PyPI than to the standard library, so I guess that it > isn't as bad a loss of face as I feared. I'm latching onto this thread just so I can bitch: I always thought "Batteries included" was a great concept, a great philosophy, a great slogan. It encouraged me to look into python because they made the tools available for you to do just about anything they want. Who ever came up with "Removing dead batteries" as a slogan, when some of those batteries still work perfectly well, needs to rethink it. Go ahead and remove code that no longer works, OK. But removing unpopular modules? That undercuts the entire philosophy of the platform, in my opinion. From grant.b.edwards at gmail.com Mon May 22 12:10:05 2023 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Mon, 22 May 2023 09:10:05 -0700 (PDT) Subject: What to use instead of nntplib? References: <469aa006-40d4-38c8-5776-fe0f9e908cf1@yahoo.co.uk> <960340a9-2f55-9e48-4bb3-b39352387935@gmail.com> <6463862f.020a0220.21ee1.48db@mx.google.com> <20230521071044.6879162343f314b305574d14@amongus.com> Message-ID: <646b93dd.050a0220.84d1.18db@mx.google.com> On 2023-05-21, Retrograde wrote: > Who ever came up with "Removing dead batteries" as a slogan, when > some of those batteries still work perfectly well, needs to rethink > it. Go ahead and remove code that no longer works, OK. But removing > unpopular modules? That undercuts the entire philosophy of the > platform, in my opinion. And one of the metrics of "popularity" seems to be "activity" (e.g. changes committed). For things that have been around for 20+ years and have all the features they need and all of the bugs fixed (and are now very stable) that lack of "activity" is interpreted as "unpopular" regardless of how many people are using the module. -- Grant From mats at wichmann.us Mon May 22 12:36:16 2023 From: mats at wichmann.us (Mats Wichmann) Date: Mon, 22 May 2023 10:36:16 -0600 Subject: Is there a Python module to parse a date like the 'date' command in Linux? In-Reply-To: References: Message-ID: <98e44c4e-a532-df52-3ea3-2a88ff46dc87@wichmann.us> On 5/20/23 13:53, Chris Green wrote: > I'm converting a bash script to python as it has become rather clumsy > in bash. > > However I have hit a problem with converting dates, the bash script > has:- > > dat=$(date --date "$1" +"%Y/%m/%d") > > and this will accept almost anything reasonably sensible that can be > interpreted as a date, in particular it accepts things like "tomorrow", > "yesterday" and "next thursday". > > Is there anything similar in Python or would I be better off simply > using os.system() to run date from the python program? > in the standard library, datetime as an addon module, dateutil (install as python-dateutil) Don't know if either are exactly what you want, but do take a look. From tjandacw at gmail.com Mon May 22 16:21:23 2023 From: tjandacw at gmail.com (Tim Williams) Date: Mon, 22 May 2023 16:21:23 -0400 Subject: Is there a Python module to parse a date like the 'date' command in Linux? In-Reply-To: <98e44c4e-a532-df52-3ea3-2a88ff46dc87@wichmann.us> References: <98e44c4e-a532-df52-3ea3-2a88ff46dc87@wichmann.us> Message-ID: On Mon, May 22, 2023 at 12:41?PM Mats Wichmann wrote: > On 5/20/23 13:53, Chris Green wrote: > > I'm converting a bash script to python as it has become rather clumsy > > in bash. > > > > However I have hit a problem with converting dates, the bash script > > has:- > > > > dat=$(date --date "$1" +"%Y/%m/%d") > > > > and this will accept almost anything reasonably sensible that can be > > interpreted as a date, in particular it accepts things like "tomorrow", > > "yesterday" and "next thursday". > > > > Is there anything similar in Python or would I be better off simply > > using os.system() to run date from the python program? > > > > in the standard library, datetime > > as an addon module, dateutil (install as python-dateutil) > > Don't know if either are exactly what you want, but do take a look. > > -- > https://mail.python.org/mailman/listinfo/python-list In particular,check out dateutil.parser. parser ? dateutil 2.8.2 documentation parser This module offers a generic date/time string parser which is able to parse most known formats to represent a date and/or time. This module attempts to be forgiving with regards to unlikely input formats, returning a datetime object even for dates which are ambiguous. If an element of a date/time stamp is omitted, the following rules are applied: From thomas at python.org Mon May 22 17:04:59 2023 From: thomas at python.org (Thomas Wouters) Date: Mon, 22 May 2023 23:04:59 +0200 Subject: [RELEASE] Python 3.12.0 beta 1 released. Message-ID: I'm pleased to announce the release of Python 3.12 beta 1 (and feature freeze for Python 3.12). https://www.python.org/downloads/release/python-3120b1/ This is a beta preview of Python 3.12 Python 3.12 is still in development. This release, 3.12.0b1, is the first of four planned beta release previews of 3.12. Beta release previews are intended to give the wider community the opportunity to test new features and bug fixes and to prepare their projects to support the new feature release. We strongly encourage maintainers of third-party Python projects to test with 3.12 during the beta phase and report issues found to [the Python bug tracker (Issues ? python/cpython ? GitHub) as soon as possible. While the release is planned to be feature complete entering the beta phase, it is possible that features may be modified or, in rare cases, deleted up until the start of the release candidate phase (Monday, 2023-07-31). Our goal is to have no ABI changes after beta 4 and as few code changes as possible after 3.12.0rc1, the first release candidate. To achieve that, it will be extremely important to get as much exposure for 3.12 as possible during the beta phase. Please keep in mind that this is a preview release and its use is not recommended for production environments. Major new features of the 3.12 series, compared to 3.11 Some of the new major new features and changes in Python 3.12 are: - New type annotation syntax for generic classes (PEP 695 ). - More flexible f-string parsing, allowing many things previously disallowed (PEP 701 ). - Even more improved error messages. More exceptions potentially caused by typos now make suggestions to the user. - Many large and small performance improvements (like PEP 709 ). - Support for the Linux perf profiler to report Python function names in traces. - The deprecated wstr and wstr_length members of the C implementation of unicode objects were removed, per PEP 623 . - In the unittest module, a number of long deprecated methods and classes were removed. (They had been deprecated since Python 3.1 or 3.2). - The deprecated smtpd and distutils modules have been removed (see PEP 594 and PEP 632 . The setuptools package (installed by default in virtualenvs and many other places) continues to provide the distutils module. - A number of other old, broken and deprecated functions, classes and methods have been removed. - Invalid backslash escape sequences in strings now warn with SyntaxWarning instead of DeprecationWarning, making them more visible. (They will become syntax errors in the future.) - The internal representation of integers has changed in preparation for performance enhancements. (This should not affect most users as it is an internal detail, but it may cause problems for Cython-generated code.) - (Hey, fellow core developer, if a feature you find important is missing from this list, let Thomas know .) For more details on the changes to Python 3.12, see What?s new in Python 3.12 . The next pre-release of Python 3.12 will be 3.12.0b2, currently scheduled for 2023-05-29. More resources Online Documentation . PEP 693 , the Python 3.12 Release Schedule. Report bugs via GitHub Issues . Help fund Python and its community . And now for something completely different As the first beta release marks the point at which we fork off the release branch from the main development branch, here?s a poem about forks in the road. Two roads diverged in a yellow wood, And sorry I could not travel both And be one traveler, long I stood And looked down one as far as I could To where it bent in the undergrowth; Then took the other, as just as fair, And having perhaps the better claim, Because it was grassy and wanted wear; Though as for that the passing there Had worn them really about the same, And both that morning equally lay In leaves, no step had trodden black. Oh, I kept the first for another day! Yet knowing how way leads on to way, I doubted if I should ever come back. I shall be telling this with a sigh Somewhere ages and ages hence: Two roads diverged in a wood, and I ? I took the one less traveled by, And that has made all the difference. *The Road Not Taken*, by Robert Frost. Enjoy the new release 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 release team, Thomas Wouters Ned Deily Steve Dower -- Thomas Wouters From Keith.S.Thompson+u at gmail.com Mon May 22 18:26:58 2023 From: Keith.S.Thompson+u at gmail.com (Keith Thompson) Date: Mon, 22 May 2023 15:26:58 -0700 Subject: What to use instead of nntplib? References: <469aa006-40d4-38c8-5776-fe0f9e908cf1@yahoo.co.uk> <960340a9-2f55-9e48-4bb3-b39352387935@gmail.com> <6463862f.020a0220.21ee1.48db@mx.google.com> <20230521071044.6879162343f314b305574d14@amongus.com> <646b93dd.050a0220.84d1.18db@mx.google.com> Message-ID: <875y8k0zpp.fsf@nosuchdomain.example.com> Grant Edwards writes: > On 2023-05-21, Retrograde wrote: >> Who ever came up with "Removing dead batteries" as a slogan, when >> some of those batteries still work perfectly well, needs to rethink >> it. Go ahead and remove code that no longer works, OK. But removing >> unpopular modules? That undercuts the entire philosophy of the >> platform, in my opinion. > > And one of the metrics of "popularity" seems to be "activity" > (e.g. changes committed). For things that have been around for 20+ > years and have all the features they need and all of the bugs fixed > (and are now very stable) that lack of "activity" is interpreted as > "unpopular" regardless of how many people are using the module. My understanding is that nntplib isn't being erased from reality, it's merely being removed from the set of modules that are provided by default. I presume that once it's removed from the core, it will still be possible to install it via pip or some other mechanism. You can disable the deprecation warning: import warnings warnings.filterwarnings("ignore", category=DeprecationWarning) import nntplib If my understanding is correct, why is this such a big problem? -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u at gmail.com Will write code for food. void Void(void) { Void(); } /* The recursive call of the void */ From skip.montanaro at gmail.com Mon May 22 19:04:57 2023 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Mon, 22 May 2023 18:04:57 -0500 Subject: What to use instead of nntplib? In-Reply-To: <875y8k0zpp.fsf@nosuchdomain.example.com> References: <469aa006-40d4-38c8-5776-fe0f9e908cf1@yahoo.co.uk> <960340a9-2f55-9e48-4bb3-b39352387935@gmail.com> <6463862f.020a0220.21ee1.48db@mx.google.com> <20230521071044.6879162343f314b305574d14@amongus.com> <646b93dd.050a0220.84d1.18db@mx.google.com> <875y8k0zpp.fsf@nosuchdomain.example.com> Message-ID: > > My understanding is that nntplib isn't being erased from reality, > it's merely being removed from the set of modules that are provided > by default. > > I presume that once it's removed from the core, it will still be > possible to install it via pip or some other mechanism. > It won't magically be available via pip unless someone steps up to maintain it as a PyPI package Skip > From grant.b.edwards at gmail.com Mon May 22 19:59:23 2023 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Mon, 22 May 2023 16:59:23 -0700 (PDT) Subject: What to use instead of nntplib? References: <469aa006-40d4-38c8-5776-fe0f9e908cf1@yahoo.co.uk> <960340a9-2f55-9e48-4bb3-b39352387935@gmail.com> <6463862f.020a0220.21ee1.48db@mx.google.com> <20230521071044.6879162343f314b305574d14@amongus.com> <646b93dd.050a0220.84d1.18db@mx.google.com> <875y8k0zpp.fsf@nosuchdomain.example.com> Message-ID: <646c01db.920a0220.78995.1ea5@mx.google.com> On 2023-05-22, Keith Thompson wrote: > My understanding is that nntplib isn't being erased from reality, > it's merely being removed from the set of modules that are provided > by default. > > I presume that once it's removed from the core, it will still be > possible to install it via pip or some other mechanism. If somebody rescues the code and puts it in Pypi (assuming the copyright owner allows that). IIRC, somebody is trying to do that, but there some contention because Pypi won't allow the use of the name "nntplib" for the package because it conflicts with a library builtin. > > import warnings > warnings.filterwarnings("ignore", category=DeprecationWarning) > import nntplib Yep, thanks. That at least prevents the warning from messing up my slrn screen. :) > If my understanding is correct, why is this such a big problem? It's not a "big" problem, but something that "just worked" with any Python installation now requires that the user install an extra package. If they don't already have pip, then they have to install that first. And then they have to do it again, because the first time they installed pip for the wrong version of python. [I don't really get how that happens, but there seem to be a constant stream of postings from people with that problem.] -- Grant From miked at dewhirst.com.au Mon May 22 20:22:49 2023 From: miked at dewhirst.com.au (Mike Dewhirst) Date: Tue, 23 May 2023 10:22:49 +1000 Subject: Is there a Python module to parse a date like the 'date' command in Linux? In-Reply-To: References: Message-ID: On 21/05/2023 5:53 am, Chris Green wrote: > I'm converting a bash script to python as it has become rather clumsy > in bash. What is the use case? > However I have hit a problem with converting dates, the bash script > has:- > > dat=$(date --date "$1" +"%Y/%m/%d") > > and this will accept almost anything reasonably sensible that can be > interpreted as a date, in particular it accepts things like "tomorrow", > "yesterday" and "next thursday". > > Is there anything similar in Python or would I be better off simply > using os.system() to run date from the python program? > -- Signed email is an absolute defence against phishing. This email has been signed with my private key. If you import my public key you can automatically decrypt my signature and be sure it came from me. Your email software can handle signing. -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature Type: application/pgp-signature Size: 495 bytes Desc: OpenPGP digital signature URL: From jon+usenet at unequivocal.eu Mon May 22 19:07:40 2023 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Mon, 22 May 2023 23:07:40 -0000 (UTC) Subject: What to use instead of nntplib? References: <469aa006-40d4-38c8-5776-fe0f9e908cf1@yahoo.co.uk> <960340a9-2f55-9e48-4bb3-b39352387935@gmail.com> <6463862f.020a0220.21ee1.48db@mx.google.com> <20230521071044.6879162343f314b305574d14@amongus.com> <646b93dd.050a0220.84d1.18db@mx.google.com> <875y8k0zpp.fsf@nosuchdomain.example.com> Message-ID: On 2023-05-22, Skip Montanaro wrote: >> My understanding is that nntplib isn't being erased from reality, >> it's merely being removed from the set of modules that are provided >> by default. >> >> I presume that once it's removed from the core, it will still be >> possible to install it via pip or some other mechanism. > > It won't magically be available via pip unless someone steps up to maintain > it as a PyPI package That would appear to have already happened over a month ago. From cl at isbd.net Tue May 23 05:16:47 2023 From: cl at isbd.net (Chris Green) Date: Tue, 23 May 2023 10:16:47 +0100 Subject: Is there a Python module to parse a date like the 'date' command in Linux? References: Message-ID: Mike Dewhirst wrote: > [-- multipart/mixed, encoding 7bit, 22 lines --] > > [-- text/plain, encoding base64, charset: UTF-8, 16 lines --] > > On 21/05/2023 5:53 am, Chris Green wrote: > > I'm converting a bash script to python as it has become rather clumsy > > in bash. > > What is the use case? > A script I use to create diary entries, so it's very handy to be able to give the date as 'yesterday' or 'friday'. -- Chris Green ? From apinkney97 at gmail.com Tue May 23 12:53:24 2023 From: apinkney97 at gmail.com (Alex Pinkney) Date: Tue, 23 May 2023 17:53:24 +0100 Subject: Is there a Python module to parse a date like the 'date' command in Linux? In-Reply-To: References: Message-ID: On Tue, 23 May 2023, 17:25 Chris Green, wrote: > Mike Dewhirst wrote: > > [-- multipart/mixed, encoding 7bit, 22 lines --] > > > > [-- text/plain, encoding base64, charset: UTF-8, 16 lines --] > > > > On 21/05/2023 5:53 am, Chris Green wrote: > > > I'm converting a bash script to python as it has become rather clumsy > > > in bash. > > > > What is the use case? > > > A script I use to create diary entries, so it's very handy to be able > to give the date as 'yesterday' or 'friday'. > > -- > Chris Green > ? > -- > https://mail.python.org/mailman/listinfo/python-list Hi, you may find dateparser useful: https://dateparser.readthedocs.io/en/latest/ From rob.cliffe at btinternet.com Sun May 21 15:30:45 2023 From: rob.cliffe at btinternet.com (Rob Cliffe) Date: Sun, 21 May 2023 20:30:45 +0100 Subject: Addition of a .= operator In-Reply-To: <435bae66-e0b8-49da-bb39-10606492b59dn@googlegroups.com> References: <435bae66-e0b8-49da-bb39-10606492b59dn@googlegroups.com> Message-ID: <08af3c3a-ba3b-0b15-554e-6ff12cbcf880@btinternet.com> On 20/05/2023 18:54, Alex Jando wrote: > I have many times had situations where I had a variable of a certain type, all I cared about it was one of it's methods. > > For example: > > ------------------------------------------------------------ > import hashlib > hash = hashlib.sha256(b'word') > hash = hash.hexdigest() > ------------------------------------------------------------ > import enum > class Number(enum.Enum): > One: int = 1 > Two: int = 2 > Three: int = 3 > num = Number.One > num = num.value > ------------------------------------------------------------ > > Now to be fair, in the two situations above, I could just access the method right as I declare the object, however, sometimes when passing values into functions, it's a lot messier to do that. > > So what I'm suggesting is something like this: > > ------------------------------------------------------------ > import hashlib > hash = hashlib.sha256(b'word') > hash.=hexdigest() > ------------------------------------------------------------ > import enum > class Number(enum.Enum): > One: int = 1 > Two: int = 2 > Three: int = 3 > num = Number.One > num.=value > ------------------------------------------------------------ It seems to me that this would encourage bad style.? When you write ??? num = num.value you are using num with two different meanings (an object and an attribute of it).? The original object is lost. If down the line you needed to access another attribute of the object, you would have to backtrack: ??? val = num.value ??? spam = num.spam or at least write the statements in the right order, so that you only overwrite num at the end: ??? spam = num.spam ??? num = num.value Either way, you are making the code more fragile i.e. harder to maintain. Now of course, in your use case it may be perfectly appropriate to write "num = num.value" as you did. But IMO it's not something that should be encouraged in general. Best wishes Rob Cliffe From hjp-python at hjp.at Tue May 23 17:03:26 2023 From: hjp-python at hjp.at (Peter J. Holzer) Date: Tue, 23 May 2023 23:03:26 +0200 Subject: Addition of a .= operator In-Reply-To: <08af3c3a-ba3b-0b15-554e-6ff12cbcf880@btinternet.com> References: <435bae66-e0b8-49da-bb39-10606492b59dn@googlegroups.com> <08af3c3a-ba3b-0b15-554e-6ff12cbcf880@btinternet.com> Message-ID: <20230523210326.cxxuju345jkqaqp5@hjp.at> On 2023-05-21 20:30:45 +0100, Rob Cliffe via Python-list wrote: > On 20/05/2023 18:54, Alex Jando wrote: > > So what I'm suggesting is something like this: > > > > ------------------------------------------------------------ > > hash = hashlib.sha256(b'word') > > hash.=hexdigest() > > ------------------------------------------------------------ > > num = Number.One > > num.=value > > ------------------------------------------------------------ > It seems to me that this would encourage bad style.? When you write > ??? num = num.value > you are using num with two different meanings (an object and an > attribute of it). I think that's ok if it's the same thing at a high level. I sometimes have a chain of transformations (e.g. first decode it, then strip extra spaces, then normalize spelling, then look it up in a database and replace it with the record, ...). Technically, of course all these intermediate objects are different, and I could make that explicit by using different variable names: user_param = request.GET["user"] user_decoded = str(user_param, encoding="utf-8") user_stripped = user_decoded.strip() user_normalized = user_stripped.lower() user_object = orm.user.get(name=user_normalized) But I find it easier to read if I just reuse the same variable name: user = request.GET["user"] user = str(user, encoding="utf-8") user = user.strip() user = user.lower() user = orm.user.get(name=user) Each instance only has a livetime of a single line (or maybe two or three lines if I have to combine variables), so there's little risk of confusion, and reusing the variable name makes it very clear that all those intermediate results are gone and won't be used again. 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 rosuav at gmail.com Tue May 23 17:12:32 2023 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 24 May 2023 07:12:32 +1000 Subject: Addition of a .= operator In-Reply-To: <20230523210326.cxxuju345jkqaqp5@hjp.at> References: <435bae66-e0b8-49da-bb39-10606492b59dn@googlegroups.com> <08af3c3a-ba3b-0b15-554e-6ff12cbcf880@btinternet.com> <20230523210326.cxxuju345jkqaqp5@hjp.at> Message-ID: On Wed, 24 May 2023 at 07:04, Peter J. Holzer wrote: > But I find it easier to read if I just reuse the same variable name: > > user = request.GET["user"] > user = str(user, encoding="utf-8") > user = user.strip() > user = user.lower() > user = orm.user.get(name=user) > > Each instance only has a livetime of a single line (or maybe two or > three lines if I have to combine variables), so there's little risk of > confusion, and reusing the variable name makes it very clear that all > those intermediate results are gone and won't be used again. > Small side point: You can make use of the bytes object's decode() method to make the chaining much more useful here, rather than the str() constructor. This sort of code might be better as a single expression. For example: user = ( request.GET["user"] .decode("utf-8") .strip() .lower() ) user = orm.user.get(name=user) The pipeline is still visible, you've avoided the "user = user ." replication, and you've ALSO avoided duplicating "user = " on each line too. IMO the ".=" syntax would actually be a bit of a nuisance in this style of code. Consider how it would look, with your original str constructor in the middle: user = request.GET["user"] user = str(user, encoding="utf-8") user .= strip() user .= lower() user = orm.user.get(name=user) The fact that two of them are ".=" rather than "=" is a bit too subtle for my liking, possibly because the dot is so small. ChrisA From rosuav at gmail.com Tue May 23 18:37:51 2023 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 24 May 2023 08:37:51 +1000 Subject: Addition of a .= operator In-Reply-To: <9d8badab-4af7-8b5b-92a3-2fc7b1ea2fec@btinternet.com> References: <435bae66-e0b8-49da-bb39-10606492b59dn@googlegroups.com> <08af3c3a-ba3b-0b15-554e-6ff12cbcf880@btinternet.com> <20230523210326.cxxuju345jkqaqp5@hjp.at> <9d8badab-4af7-8b5b-92a3-2fc7b1ea2fec@btinternet.com> Message-ID: On Wed, 24 May 2023 at 08:22, Rob Cliffe wrote: > > > > This sort of code might be better as a single expression. For example: > > > > user = ( > > request.GET["user"] > > .decode("utf-8") > > .strip() > > .lower() > > ) > > user = orm.user.get(name=user) > > > > > LOL. And I thought I was the one with a (self-confessed) tendency to > write too slick, dense, smart-alec code. ? > Indeed, I was itching to shorten it (starting with the low-hanging > fruit: user = user.strip().lower() ). > Seriously though: this kind of condensation can come unstuck when any of > the steps need to be made more complicated. > (Suppose request.GET might return ASCII, might return Unicode, depending > on which server it was talking to.) Do you mean "ASCII or UTF-8"? Because decoding as UTF-8 is fine with ASCII (it's a superset). You should always consistently get the same data type (bytes or text) based on the library you're using. ChrisA From rob.cliffe at btinternet.com Tue May 23 18:21:17 2023 From: rob.cliffe at btinternet.com (Rob Cliffe) Date: Tue, 23 May 2023 23:21:17 +0100 Subject: Addition of a .= operator In-Reply-To: References: <435bae66-e0b8-49da-bb39-10606492b59dn@googlegroups.com> <08af3c3a-ba3b-0b15-554e-6ff12cbcf880@btinternet.com> <20230523210326.cxxuju345jkqaqp5@hjp.at> Message-ID: <9d8badab-4af7-8b5b-92a3-2fc7b1ea2fec@btinternet.com> > This sort of code might be better as a single expression. For example: > > user = ( > request.GET["user"] > .decode("utf-8") > .strip() > .lower() > ) > user = orm.user.get(name=user) > > LOL.? And I thought I was the one with a (self-confessed) tendency to write too slick, dense, smart-alec code. ? Indeed, I was itching to shorten it (starting with the low-hanging fruit: user = user.strip().lower() ). Seriously though: this kind of condensation can come unstuck when any of the steps need to be made more complicated. (Suppose request.GET might return ASCII, might return Unicode, depending on which server it was talking to.) Peter's actual code feels more Pythonic to me.? (It's even 2 lines shorter! ?) Rob Cliffe From hjp-python at hjp.at Tue May 23 18:46:38 2023 From: hjp-python at hjp.at (Peter J. Holzer) Date: Wed, 24 May 2023 00:46:38 +0200 Subject: Addition of a .= operator In-Reply-To: References: <435bae66-e0b8-49da-bb39-10606492b59dn@googlegroups.com> <08af3c3a-ba3b-0b15-554e-6ff12cbcf880@btinternet.com> <20230523210326.cxxuju345jkqaqp5@hjp.at> Message-ID: <20230523224638.vigjgnrqqdnmcmvm@hjp.at> On 2023-05-24 07:12:32 +1000, Chris Angelico wrote: > On Wed, 24 May 2023 at 07:04, Peter J. Holzer wrote: > > But I find it easier to read if I just reuse the same variable name: > > > > user = request.GET["user"] > > user = str(user, encoding="utf-8") > > user = user.strip() > > user = user.lower() > > user = orm.user.get(name=user) > > > > Each instance only has a livetime of a single line (or maybe two or > > three lines if I have to combine variables), so there's little risk of > > confusion, and reusing the variable name makes it very clear that all > > those intermediate results are gone and won't be used again. > > > > Small side point: You can make use of the bytes object's decode() > method to make the chaining much more useful here, rather than the > str() constructor. > > This sort of code might be better as a single expression. For example: > > user = ( > request.GET["user"] > .decode("utf-8") > .strip() > .lower() > ) > user = orm.user.get(name=user) Yes, that probably wasn't the best example. I sort of deliberately avoided method chaining here to make my point that you don't have to invent a new variable name for every intermediate result, but of course that backfired because in this case you don't need a variable name at all. I should have used regular function calls ... 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 rosuav at gmail.com Tue May 23 18:51:19 2023 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 24 May 2023 08:51:19 +1000 Subject: Addition of a .= operator In-Reply-To: <20230523224638.vigjgnrqqdnmcmvm@hjp.at> References: <435bae66-e0b8-49da-bb39-10606492b59dn@googlegroups.com> <08af3c3a-ba3b-0b15-554e-6ff12cbcf880@btinternet.com> <20230523210326.cxxuju345jkqaqp5@hjp.at> <20230523224638.vigjgnrqqdnmcmvm@hjp.at> Message-ID: On Wed, 24 May 2023 at 08:48, Peter J. Holzer wrote: > > On 2023-05-24 07:12:32 +1000, Chris Angelico wrote: > > On Wed, 24 May 2023 at 07:04, Peter J. Holzer wrote: > > > But I find it easier to read if I just reuse the same variable name: > > > > > > user = request.GET["user"] > > > user = str(user, encoding="utf-8") > > > user = user.strip() > > > user = user.lower() > > > user = orm.user.get(name=user) > > > > > > Each instance only has a livetime of a single line (or maybe two or > > > three lines if I have to combine variables), so there's little risk of > > > confusion, and reusing the variable name makes it very clear that all > > > those intermediate results are gone and won't be used again. > > > > > > > Small side point: You can make use of the bytes object's decode() > > method to make the chaining much more useful here, rather than the > > str() constructor. > > > > This sort of code might be better as a single expression. For example: > > > > user = ( > > request.GET["user"] > > .decode("utf-8") > > .strip() > > .lower() > > ) > > user = orm.user.get(name=user) > > Yes, that probably wasn't the best example. I sort of deliberately > avoided method chaining here to make my point that you don't have to > invent a new variable name for every intermediate result, but of course > that backfired because in this case you don't need a variable name at > all. I should have used regular function calls ... > In the context of a .= operator, though, that is *in itself* an interesting data point: in order to find an example wherein the .= operator would be plausible, you had to make the .= operator unnecessary. ChrisA From rosuav at gmail.com Tue May 23 19:04:42 2023 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 24 May 2023 09:04:42 +1000 Subject: Addition of a .= operator In-Reply-To: References: <435bae66-e0b8-49da-bb39-10606492b59dn@googlegroups.com> <08af3c3a-ba3b-0b15-554e-6ff12cbcf880@btinternet.com> <20230523210326.cxxuju345jkqaqp5@hjp.at> <9d8badab-4af7-8b5b-92a3-2fc7b1ea2fec@btinternet.com> Message-ID: On Wed, 24 May 2023 at 08:57, Rob Cliffe wrote: > > Do you mean "ASCII or UTF-8"? Because decoding as UTF-8 is fine with > > ASCII (it's a superset). You should always consistently get the same > > data type (bytes or text) based on the library you're using. > > > > ChrisA > OK, bad example. The point remains: condensing each step to a single > chained function can come unstuck when one of the steps needs to be made > more complicated for some reason. That's fair. Still, I wouldn't over-complicate a piece of code "just in case" it needs to become more complicated in the future. I'd rather code to what's needed now, and if that's a simple "decode as UTF-8", that's great; maybe in the future I need to cope with an insane system like "decode line by line, attempting UTF-8 first and falling back on Windows-1252, then rejoin the lines", and that's the time to implement that. (Yes, I have had to do that. Although I think I cheated and used ISO-8859-1 instead. It was a lot easier and I didn't really care about precise handling, so long as MOST things were readable.) ChrisA From rob.cliffe at btinternet.com Tue May 23 18:06:52 2023 From: rob.cliffe at btinternet.com (Rob Cliffe) Date: Tue, 23 May 2023 23:06:52 +0100 Subject: Addition of a .= operator In-Reply-To: <20230523210326.cxxuju345jkqaqp5@hjp.at> References: <435bae66-e0b8-49da-bb39-10606492b59dn@googlegroups.com> <08af3c3a-ba3b-0b15-554e-6ff12cbcf880@btinternet.com> <20230523210326.cxxuju345jkqaqp5@hjp.at> Message-ID: <507eadb0-af09-21ee-6176-12b7d96915e8@btinternet.com> On 23/05/2023 22:03, Peter J. Holzer wrote: > On 2023-05-21 20:30:45 +0100, Rob Cliffe via Python-list wrote: >> On 20/05/2023 18:54, Alex Jando wrote: >>> So what I'm suggesting is something like this: >>> >>> ------------------------------------------------------------ >>> hash = hashlib.sha256(b'word') >>> hash.=hexdigest() >>> ------------------------------------------------------------ >>> num = Number.One >>> num.=value >>> ------------------------------------------------------------ >> It seems to me that this would encourage bad style.? When you write >> ??? num = num.value >> you are using num with two different meanings (an object and an >> attribute of it). > I think that's ok if it's the same thing at a high level. > > I sometimes have a chain of transformations (e.g. first decode it, then > strip extra spaces, then normalize spelling, then look it up in a > database and replace it with the record, ...). Technically, of course > all these intermediate objects are different, and I could make that > explicit by using different variable names: > > user_param = request.GET["user"] > user_decoded = str(user_param, encoding="utf-8") > user_stripped = user_decoded.strip() > user_normalized = user_stripped.lower() > user_object = orm.user.get(name=user_normalized) > > But I find it easier to read if I just reuse the same variable name: > > user = request.GET["user"] > user = str(user, encoding="utf-8") > user = user.strip() > user = user.lower() > user = orm.user.get(name=user) > > Each instance only has a livetime of a single line (or maybe two or > three lines if I have to combine variables), so there's little risk of > confusion, and reusing the variable name makes it very clear that all > those intermediate results are gone and won't be used again. > > hp > > > Quite so.? I did imply in my full answer that this kind of thing can be appropriate in the right context.? I'm sure I've done it myself. Your code is a beautiful example of when such "level-crossing" IS appropriate; creating a plethora of variables with a short useful life would be a distraction which HINDERS readability ("Are any of these variables used later on?"). (Not to mention the effort of thinking up suitable variable names, and the effort of someone reading the code to assimilate them.) But IMO your code would not really benefit from writing ??? ??? user .= strip() ??? ??? user .= lower() and allowing it would have the disadvantage (apart from all the known costs of adding a new feature to Python) of encouraging bad style in the cases where it IS bad style. Best wishes Rob Cliffe From PythonList at DancesWithMice.info Tue May 23 20:10:09 2023 From: PythonList at DancesWithMice.info (dn) Date: Wed, 24 May 2023 12:10:09 +1200 Subject: OT: Addition of a .= operator In-Reply-To: <9d8badab-4af7-8b5b-92a3-2fc7b1ea2fec@btinternet.com> References: <435bae66-e0b8-49da-bb39-10606492b59dn@googlegroups.com> <08af3c3a-ba3b-0b15-554e-6ff12cbcf880@btinternet.com> <20230523210326.cxxuju345jkqaqp5@hjp.at> <9d8badab-4af7-8b5b-92a3-2fc7b1ea2fec@btinternet.com> Message-ID: <7485cf2f-f9ff-7891-024e-b1e395a6bb6a@DancesWithMice.info> On 24/05/2023 10.21, Rob Cliffe via Python-list wrote: > >> This sort of code might be better as a single expression. For example: >> >> user = ( >> ???? request.GET["user"] >> ???? .decode("utf-8") >> ???? .strip() >> ???? .lower() >> ) >> user = orm.user.get(name=user) >> >> > LOL.? And I thought I was the one with a (self-confessed) tendency to > write too slick, dense, smart-alec code. ? > Indeed, I was itching to shorten it (starting with the low-hanging > fruit: user = user.strip().lower() ). > Seriously though: this kind of condensation can come unstuck when any of > the steps need to be made more complicated. ... > Peter's actual code feels more Pythonic to me.? (It's even 2 lines > shorter! ?) On 24/05/2023 09.03, Peter J. Holzer wrote: > I sometimes have a chain of transformations (e.g. first decode it, then > strip extra spaces, then normalize spelling, then look it up in a > database and replace it with the record, ...). Technically, of course > all these intermediate objects are different, and I could make that > explicit by using different variable names: > > user_param = request.GET["user"] > user_decoded = str(user_param, encoding="utf-8") > user_stripped = user_decoded.strip() > user_normalized = user_stripped.lower() > user_object = orm.user.get(name=user_normalized) > > But I find it easier to read if I just reuse the same variable name: > > user = request.GET["user"] > user = str(user, encoding="utf-8") > user = user.strip() > user = user.lower() > user = orm.user.get(name=user) > > Each instance only has a livetime of a single line (or maybe two or > three lines if I have to combine variables), so there's little risk of > confusion, and reusing the variable name makes it very clear that all > those intermediate results are gone and won't be used again. Once again/recently/another trainee came with a question about input() because he expected an number (cf input() providing a string). In this case, and to drive-home the point, preferred training illustration is: quantity_input = input( "How many would you like? " ) quantity = float( quantity_input ) Many others, and I dare so all those who suffer from the aforementioned "itch", want to condense this into a single line. However, (continuing @Peter's theme) such confuses things when something goes wrong - was the error in the input() or in the float()? - particularly for 'beginners' - and yes, we can expand the above discussion to talk about error-handling, and repetition until satisfactory data is input by the user or (?frustration leads to) EOD... Accordingly, I'd start by favoring @Peter's "explicit" approach. However (as mentioned), we end-up with a bunch of names (storage-space) which are essentially unused - and many lint-er types will deplore such single-use [like it's s-u plastic]. Thus, advice becomes somewhat the opposite(!) of function parameter handling - there, I'm happy with one or two positional-parameters, but by three-or-more, this over-taxed brain starts begging/itching for named-parameters instead. Now, the "easier" approach appeals. Indeed, if something goes wrong (per input()/float(), above), at least one has the assistance of a line-number (where error was noted). Further, using the PyCharm Debugger/pdb makes locating the design-error/coder's mistaken assumption, a snap. A debatable-point is how much we should consider more junior-level programmers. IMHO more common functions such as strip() and lower() can be combined without much loss of readability or comprehension (apart from 'function-chaining' adding complication). Whereas, the other three lines are more likely to challenge - and/or become a source of concern if mods are requested... However, some disagreement - which comes back to why the "_input" suffix (above) acts as an aide-memoire: When "user" is first used (hah!), it is the result of an http request. It is then transmogrified, until at the end where it is a query-result/object. Yes, however contrived and deliberately drawn-out the example, there is still a difference between the value which the code first produces (request/input) and that which eventually settles-out (orm/float). Accordingly (perhaps), "user_request" or "user_requested" and "user" or "user_record" (according to the way 'that' ORM operates). Perhaps more psychology rather than coding? -- Regards, =dn From rosuav at gmail.com Tue May 23 20:27:52 2023 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 24 May 2023 10:27:52 +1000 Subject: OT: Addition of a .= operator In-Reply-To: <7485cf2f-f9ff-7891-024e-b1e395a6bb6a@DancesWithMice.info> References: <435bae66-e0b8-49da-bb39-10606492b59dn@googlegroups.com> <08af3c3a-ba3b-0b15-554e-6ff12cbcf880@btinternet.com> <20230523210326.cxxuju345jkqaqp5@hjp.at> <9d8badab-4af7-8b5b-92a3-2fc7b1ea2fec@btinternet.com> <7485cf2f-f9ff-7891-024e-b1e395a6bb6a@DancesWithMice.info> Message-ID: On Wed, 24 May 2023 at 10:12, dn via Python-list wrote: > However, (continuing @Peter's theme) such confuses things when something > goes wrong - was the error in the input() or in the float()? > - particularly for 'beginners' > - and yes, we can expand the above discussion to talk about > error-handling, and repetition until satisfactory data is input by the > user or (?frustration leads to) EOD... A fair consideration! Fortunately, Python has you covered. $ cat asin.py import math print( math.asin( float( input("Enter a small number: ") ) ) ) $ python3 asin.py Enter a small number: 1 1.5707963267948966 $ python3 asin.py Enter a small number: 4 Traceback (most recent call last): File "/home/rosuav/tmp/asin.py", line 4, in math.asin( ValueError: math domain error $ python3 asin.py Enter a small number: spam Traceback (most recent call last): File "/home/rosuav/tmp/asin.py", line 5, in float( ValueError: could not convert string to float: 'spam' Note that the line numbers correctly show the true cause of the problem, despite both of them being ValueErrors. So if you have to debug this sort of thing, make sure the key parts are on separate lines (even if they're all one expression, as in this example), and then the tracebacks should tell you what you need to know. ChrisA From richosborne at outlook.com Tue May 23 20:14:02 2023 From: richosborne at outlook.com (Rich Osborne) Date: Wed, 24 May 2023 00:14:02 +0000 Subject: where is requests Message-ID: I have install Python 3.11.3 but my import requests does not work. I found documentation that refers to C:\python35 but I am on 3.11.3. Where do I find requests? Sent from Mail for Windows From python at mrabarnett.plus.com Tue May 23 22:27:58 2023 From: python at mrabarnett.plus.com (MRAB) Date: Wed, 24 May 2023 03:27:58 +0100 Subject: where is requests In-Reply-To: References: Message-ID: On 2023-05-24 01:14, Rich Osborne wrote: > I have install Python 3.11.3 but my import requests does not work. I found documentation that refers to C:\python35 but I am on 3.11.3. Where do I find requests? > It's not part of the standard library. You can import it using pip. If you're on Windows, the recommended method is o use the Python Launcher and the pip module from a Command Prompt window: py -m pip install requests From rob.cliffe at btinternet.com Tue May 23 21:18:07 2023 From: rob.cliffe at btinternet.com (Rob Cliffe) Date: Wed, 24 May 2023 02:18:07 +0100 Subject: Tkinter docs? Message-ID: I have recently started converting a large project to tkinter, starting with zero knowledge of tkinter.? (You are free to think: BAD IDEA. ?) I am well aware that adopting a new tool always involves a learning curve, and that one is prone to think that things are more difficult than they are/should be, and to belly-ache about it, and that in a year from now I'll probably wonder what I'm fussing about. Nonetheless ISTM that there is a particular problem with tkinter: ??? There doesn't seem to be any decent documentation for it anywhere. ?I seem to have spent al least 95% (feels more like 99%) of my time in research, only the rest available for coding.? Everything I've learned has come from scouring the Internet for Stack Overflow pages, videos, and other articles.? And while I'm VERY grateful for these resources, most of them cover very basic use, and if I want information on some more obscure technical point, I can only go on looking and looking and hope I eventually stumble upon what I'm looking for, or some acceptable substitute. FWIW: The tkinter error messages are sometimes helpful, sometimes not, occasionally very helpful (as when I pass an invalid option parameter to a function and it tells me what the valid ones are).? I feel there is plenty of room for improvement. One example for those familiar with tkinter (I assure you there are others) of how I struggle without adequate documentation: ??? I had learned very early on that tkinter provides two versions of some classes: the original, or "tk" versions, and a later generation, the "ttk" versions (and I have to say that that was a turn-off, as it seemed that the learning curve has just got steeper).? It was surely not appropriate for me to delve deeply into this issue at that stage, as there were so many other things I didn't know (like, practically everything).? I decide to go with the "tk" versions pro tem, and to investigate the "ttk" versions later if it seemed like a good idea.? One annoyance is that some webpages are relevant to one version, some to the other, almost always without being explicit about which.? (Can't blame the "tk" ones, as they were probably written before "ttk" was invented.) ??? I was writing a subclass of the Checkbutton class (tkinter's name for what I call a checkbox).? I needed to be able to (1) set (2) clear (3) interrogate the checked state.? This is easy to do if you associate a "variable" with each Checkbutton instance, as seems to be usual tkinter practice.? ("variable" is not a variable in the usual sense, but an object provided by tkinter that is linked to a GUI object (such as a Checkbutton), so that when the GUI object changes, the value of the "variable" changes, and vice versa.) However, I decided that I wanted to dispense with the variable, if possible.? (My motivation?? Simpler code.? Shorter code.? Avoiding using up resources by creating unnecessary objects.? You are free to think that I was misguided.? You are free to think that I should have been happy with something that worked.)? I didn't care whether I used a tk.Checkbutton or a ttk.Checkbutton. ??? From various Internet articles I discovered (slowly, after wading through many articles that DID use a "variable"): ??? ??? A way of GETting the state of a tk.CheckButton (but not a ttk.CheckButton) ??? ??? A way of SETting the state of a ttk.CheckButton (but not a tk.CheckButton) ??? ??? Or the other way round.? Or something else.? I can no longer remember, and I didn't keep a record of all my trials and tribulations, and I can no longer trace which articles I read when. ??? EVENTUALLY I discovered: ??? ??? For a ttk.CheckButton (only), where cb is the checkbox ??? ??? ??? cb.state() returns a tuple of strings which contains, or doesn't, "selected", according to the checked state ??? ??? ??? cb.state(["selected"]) sets the checked state ??? ??? ??? cb.state(["!selected"]) clears the checked state "Aha!" I thought.? "Problem solved".? Gleefully I wrote my code and tested it. Er, well, not quite.? When the Checkbutton object was instantiated, it showed neither a checked nor an unchecked box, but a solid black box.? This was the third or so-called "alternate" state provided by tkinter.? (Gee, thanks.? Oh sorry, it's probably not your fault; as I understand it, tkinter, you're really just a wrapper.) Further research revealed that I could get past this by writing ??? cb.state(["!alternate", "!selected"]) when the object was instantiated. Phew!? Finally got my code working. But the story is not quite over.? To get the checked state I was using ??? "selected" in cb.state() While this works, later (in fact while composing this e-mail) I stumbled across ??? cb.instate(["selected"]) which does the same thing but is, I guess, the preferred method.? I have amended my code accordingly. (I don't know why the square brackets are necessary, but ??? cb.instate("selected") doesn't work.) Sigh.? I suppose I have the satisfaction of having overcome a challenge.? But how much nicer if all this information were in one place somewhere. Now, my remarks are as a tk newbie; they may be naive and ignorant, perhaps even laughable.? But IMO it is often worth listening to input from newbies to consider how things might be improved. Comments, anyone? Better yet (holds breath ...) can anyone point me towards some decent tkinter documentation? Best wishes Rob Cliffe From grant.b.edwards at gmail.com Tue May 23 23:26:24 2023 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Tue, 23 May 2023 20:26:24 -0700 (PDT) Subject: Tkinter docs? References: Message-ID: <646d83e0.050a0220.5128f.338f@mx.google.com> On 2023-05-24, Rob Cliffe via Python-list wrote: > I have recently started converting a large project to tkinter, starting > with zero knowledge of tkinter.? (You are free to think: BAD IDEA. ?) Well, you could be translating them to Tcl/Tk -- so on the scale of bad ideas, your's barely registers. > I am well aware that adopting a new tool always involves a learning > curve, and that one is prone to think that things are more difficult > than they are/should be, and to belly-ache about it, and that in a year > from now I'll probably wonder what I'm fussing about. > Nonetheless ISTM that there is a particular problem with tkinter: > > There doesn't seem to be any decent documentation for it anywhere. Back in the day, the Grayson book was the definitive reference: https://www.amazon.com/Python-Tkinter-Programming-John-Grayson/dp/1884777813/ It's 20+ years old now, so the version of Python it uses is pretty ancient, and I presume Tk has also changed a bit over the years, so... There are a couple recent books, but I haven't looked at them: https://www.amazon.com/Modern-Tkinter-Busy-Python-Developers-dp-1999149564/dp/1999149564/ https://www.amazon.com/Python-GUI-Programming-Tkinter-user-friendly/dp/1801815925/ -- Grant From miked at dewhirst.com.au Tue May 23 23:42:07 2023 From: miked at dewhirst.com.au (Mike Dewhirst) Date: Wed, 24 May 2023 13:42:07 +1000 Subject: where is requests In-Reply-To: Message-ID: <4QQxpF3zvtznV2P@mail.python.org> Try pip install requests--(Unsigned mail from my phone) -------- Original message --------From: Rich Osborne Date: 24/5/23 11:49 (GMT+10:00) To: python-list at python.org Subject: where is requests I have install Python 3.11.3 but my import requests does not work. I found documentation that refers to C:\python35 but I am on 3.11.3. Where do I find requests?Sent from Mail for Windows-- https://mail.python.org/mailman/listinfo/python-list From aapost at idontexist.club Wed May 24 00:00:56 2023 From: aapost at idontexist.club (aapost) Date: Wed, 24 May 2023 00:00:56 -0400 Subject: Tkinter docs? In-Reply-To: References: Message-ID: On 5/23/23 21:18, Rob Cliffe wrote: > Comments, anyone? > Better yet (holds breath ...) can anyone point me towards some decent > tkinter documentation? The variables are slightly more integrated when using tcl/tk directly, python has to have the object so you can track/use them easier. And the variables are more of what is intended to track a widgets purpose, vs state stuff that is more the state of the displaying of the widget. occasionally giving tcl/tk a try directly helps, and using the official tcl/tk docs in addition to a couple other decent docs below. https://anzeljg.github.io/rin2/book2/2405/docs/tkinter/index.html https://tkdocs.com/tutorial/styles.html https://www.tcl.tk/man/tcl8.6/ https://www.tcl.tk/man/tcl8.6/TkCmd/contents.html https://www.tcl.tk/man/tcl8.6/TkLib/contents.html (this used to be some documentation that I only discovered existed recently, but most of it doesn't load and I don't know that anyone backed it up for rehosting..) https://web.archive.org/web/20200227170827/http://effbot.org/tkinterbook tk is decent for what it can do, (and it could do potentially more if you had a lifetime to dedicate to it, lol) and it's reasonably stable and not being perpetually hacked about and broken like gtk. A couple additional pointers in case these haven't been figured out yet: Running it interactively and using tab complete helps. If you are running an app you can comment out the mytk.mainloop() statement then run python -i yourtk.py to give you access to all widgets live. For navigating them, just come up with a widget naming convention that works for you in a similar vein to how tk does (like .frame.frame.label to start), i.e. main = tk.Tk() main.frame = tk.Frame() That way if you have anchored your widgets to something at the root level you can navigate down to whatever you are looking for easily. (you can also use winfo_children() iteratively to travel the way tcl structures them, but that is tedious). From PythonList at DancesWithMice.info Wed May 24 01:18:52 2023 From: PythonList at DancesWithMice.info (dn) Date: Wed, 24 May 2023 17:18:52 +1200 Subject: OT: Addition of a .= operator In-Reply-To: References: <435bae66-e0b8-49da-bb39-10606492b59dn@googlegroups.com> <08af3c3a-ba3b-0b15-554e-6ff12cbcf880@btinternet.com> <20230523210326.cxxuju345jkqaqp5@hjp.at> <9d8badab-4af7-8b5b-92a3-2fc7b1ea2fec@btinternet.com> <7485cf2f-f9ff-7891-024e-b1e395a6bb6a@DancesWithMice.info> Message-ID: <23670349-c935-f10a-af48-f21862b28736@DancesWithMice.info> On 24/05/2023 12.27, Chris Angelico wrote: > On Wed, 24 May 2023 at 10:12, dn via Python-list wrote: >> However, (continuing @Peter's theme) such confuses things when something >> goes wrong - was the error in the input() or in the float()? >> - particularly for 'beginners' >> - and yes, we can expand the above discussion to talk about >> error-handling, and repetition until satisfactory data is input by the >> user or (?frustration leads to) EOD... > > A fair consideration! Fortunately, Python has you covered. > > $ cat asin.py > import math > > print( > math.asin( > float( > input("Enter a small number: ") > ) > ) > ) > $ python3 asin.py > Enter a small number: 1 > 1.5707963267948966 > $ python3 asin.py > Enter a small number: 4 > Traceback (most recent call last): > File "/home/rosuav/tmp/asin.py", line 4, in > math.asin( > ValueError: math domain error > $ python3 asin.py > Enter a small number: spam > Traceback (most recent call last): > File "/home/rosuav/tmp/asin.py", line 5, in > float( > ValueError: could not convert string to float: 'spam' > > Note that the line numbers correctly show the true cause of the > problem, despite both of them being ValueErrors. So if you have to > debug this sort of thing, make sure the key parts are on separate > lines (even if they're all one expression, as in this example), and > then the tracebacks should tell you what you need to know. Yes, an excellent example to show newcomers to make use of 'the information *provided*' - take a deep breath and read through it all, picking-out the important information... However, returning to "condense this into a single line", the frequently-seen coding is (in my experience, at least): quantity = float( input( "How many would you like? " ) ) which would not produce the helpful distinction between line-numbers/function-calls which the above (better-formatted) code does! Summarising (albeit IMHO): - if relatively trivial/likely to be well-known: collect the calls into a chain, eg user = user.strip().lower() - otherwise use separate lines in order to benefit from the stack-trace - (still saying) use separate assignments, rather than chaining more complex/lesser-known combinations - ensure that the 'final' identifier is meaningful (and perhaps the first, and/or even an 'intermediate' if pertinent or kept for re-use later) - perhaps re-use a single identifier-name as a temp-variable, if can reasonably 'get away with it' (and not confuse simple minds, like yours-truly) -- Regards, =dn From rosuav at gmail.com Wed May 24 02:37:52 2023 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 24 May 2023 16:37:52 +1000 Subject: Tkinter docs? In-Reply-To: References: Message-ID: On Wed, 24 May 2023 at 13:11, Rob Cliffe via Python-list wrote: > > I have recently started converting a large project to tkinter, starting > with zero knowledge of tkinter. (You are free to think: BAD IDEA. ?) > I am well aware that adopting a new tool always involves a learning > curve, and that one is prone to think that things are more difficult > than they are/should be, and to belly-ache about it, and that in a year > from now I'll probably wonder what I'm fussing about. Yes, I do think this is a bad idea, though not an abysmal one. I would recommend first playing with tkinter in a dedicated UI-only project before converting the main project to it. Your code in the scratch project can be as messy as it likes, and then you learn from it before tackling the big one :) But your concerns about tkinter's documentation are, sadly, well-founded. Since it's this weird system of thin wrappers around Tcl/Tk, a lot of things are basically just "go read the Tk docs". There are a few key concepts you'll need to get your head around, and I can't go into details because I never truly got *my* head around them... but mostly, the way that variables are used and what happens when events fire. Good luck with it. I'll be frank, building a GUI can be pretty hard... I'm still unsure whether the best way is to use something like tkinter, or to build a web app, pop up a browser window, and establish a websocket to communicate between your JavaScript front end and your Python back end. Yeah, that's how bad GUI building can be sometimes - it is potentially *easier* to build two halves of your app in two different languages than to make your GUI work the way you want it. ChrisA From miked at dewhirst.com.au Wed May 24 04:00:28 2023 From: miked at dewhirst.com.au (Mike Dewhirst) Date: Wed, 24 May 2023 18:00:28 +1000 Subject: Is there a Python module to parse a date like the 'date' command in Linux? In-Reply-To: References: Message-ID: <35891e6a-ef32-9497-bdc7-221d0ead167b@dewhirst.com.au> On 23/05/2023 7:16 pm, Chris Green wrote: > Mike Dewhirst wrote: >> [-- multipart/mixed, encoding 7bit, 22 lines --] >> >> [-- text/plain, encoding base64, charset: UTF-8, 16 lines --] >> >> On 21/05/2023 5:53 am, Chris Green wrote: >>> I'm converting a bash script to python as it has become rather clumsy >>> in bash. >> What is the use case? >> > A script I use to create diary entries, so it's very handy to be able > to give the date as 'yesterday' or 'friday'. OK - I thought maybe baklabel might suit, but that delivers a day-name (backup filename prefix) for today or a given date > -- Signed email is an absolute defence against phishing. This email has been signed with my private key. If you import my public key you can automatically decrypt my signature and be sure it came from me. Your email software can handle signing. -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature Type: application/pgp-signature Size: 495 bytes Desc: OpenPGP digital signature URL: From avi.e.gross at gmail.com Wed May 24 09:53:47 2023 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Wed, 24 May 2023 09:53:47 -0400 Subject: OT: Addition of a .= operator In-Reply-To: <23670349-c935-f10a-af48-f21862b28736@DancesWithMice.info> References: <435bae66-e0b8-49da-bb39-10606492b59dn@googlegroups.com> <08af3c3a-ba3b-0b15-554e-6ff12cbcf880@btinternet.com> <20230523210326.cxxuju345jkqaqp5@hjp.at> <9d8badab-4af7-8b5b-92a3-2fc7b1ea2fec@btinternet.com> <7485cf2f-f9ff-7891-024e-b1e395a6bb6a@DancesWithMice.info> <23670349-c935-f10a-af48-f21862b28736@DancesWithMice.info> Message-ID: <005401d98e47$29e36190$7daa24b0$@gmail.com> It may be a matter of taste and policies, Dave. I am talking about whether to write your code so it looks good to you, and dealing with issues like error messages only when needed, or whether to first do all kinds of things to catch errors or make it easier if they pop up. Python can be written fairly compactly and elegantly when trying out an algorithm. But if you pepper it with print statements all over the place showing the current values of variables and return codes (perhaps commented out or hiding in an IF statement set to False) then you have a version harder to read even if it can potentially be very useful. If your code is constantly specifying what types variables must be or testing constraints, it may well compile but for some users all that gets in the way of seeing the big picture. In this case, we are discussing issues like how to spread code onto multiple lines and opinions differ. In languages that do not use indentation as having special meaning, I often like to stretch out and use lots of lines for something like a function call with umpteen arguments and especially one containing nested similar dense function calls. A good text editor can be helpful in lining up the code so things at the same indentation level have meaning as do things at other levels. I will say that the try/catch type idioms that surround every piece of code, often nested, can make code unreadable. Similarly, some languages make it easy to do chaining in ways that use multiple lines. Since python is (justifiably) picky about indentation, I use such features less and more cautiously and sometimes need to carefully do things like add parentheses around a region to avoid inadvertent misunderstandings. When I do my work for myself and am not expecting serious errors I tend to write the main program first and only then enhance it as needed. If working with a group and established standards, of course, we follow whatever methods are needed, and especially if a large part of the effort is to test thoroughly against requirements. -----Original Message----- From: Python-list On Behalf Of dn via Python-list Sent: Wednesday, May 24, 2023 1:19 AM To: python-list at python.org Subject: Re: OT: Addition of a .= operator On 24/05/2023 12.27, Chris Angelico wrote: > On Wed, 24 May 2023 at 10:12, dn via Python-list wrote: >> However, (continuing @Peter's theme) such confuses things when something >> goes wrong - was the error in the input() or in the float()? >> - particularly for 'beginners' >> - and yes, we can expand the above discussion to talk about >> error-handling, and repetition until satisfactory data is input by the >> user or (?frustration leads to) EOD... > > A fair consideration! Fortunately, Python has you covered. > > $ cat asin.py > import math > > print( > math.asin( > float( > input("Enter a small number: ") > ) > ) > ) > $ python3 asin.py > Enter a small number: 1 > 1.5707963267948966 > $ python3 asin.py > Enter a small number: 4 > Traceback (most recent call last): > File "/home/rosuav/tmp/asin.py", line 4, in > math.asin( > ValueError: math domain error > $ python3 asin.py > Enter a small number: spam > Traceback (most recent call last): > File "/home/rosuav/tmp/asin.py", line 5, in > float( > ValueError: could not convert string to float: 'spam' > > Note that the line numbers correctly show the true cause of the > problem, despite both of them being ValueErrors. So if you have to > debug this sort of thing, make sure the key parts are on separate > lines (even if they're all one expression, as in this example), and > then the tracebacks should tell you what you need to know. Yes, an excellent example to show newcomers to make use of 'the information *provided*' - take a deep breath and read through it all, picking-out the important information... However, returning to "condense this into a single line", the frequently-seen coding is (in my experience, at least): quantity = float( input( "How many would you like? " ) ) which would not produce the helpful distinction between line-numbers/function-calls which the above (better-formatted) code does! Summarising (albeit IMHO): - if relatively trivial/likely to be well-known: collect the calls into a chain, eg user = user.strip().lower() - otherwise use separate lines in order to benefit from the stack-trace - (still saying) use separate assignments, rather than chaining more complex/lesser-known combinations - ensure that the 'final' identifier is meaningful (and perhaps the first, and/or even an 'intermediate' if pertinent or kept for re-use later) - perhaps re-use a single identifier-name as a temp-variable, if can reasonably 'get away with it' (and not confuse simple minds, like yours-truly) -- Regards, =dn -- https://mail.python.org/mailman/listinfo/python-list From auriocus at gmx.de Wed May 24 02:48:44 2023 From: auriocus at gmx.de (Christian Gollwitzer) Date: Wed, 24 May 2023 08:48:44 +0200 Subject: Tkinter docs? In-Reply-To: References: Message-ID: Am 24.05.23 um 03:18 schrieb Rob Cliffe: > I have recently started converting a large project to tkinter, starting > with zero knowledge of tkinter.? (You are free to think: BAD IDEA. ?) Welcome to the awesome world of GUI development. > ??? I was writing a subclass of the Checkbutton class (tkinter's name > for what I call a checkbox).? I needed to be able to (1) set (2) clear > (3) interrogate the checked state.? This is easy to do if you associate > a "variable" with each Checkbutton instance, as seems to be usual > tkinter practice.? ("variable" is not a variable in the usual sense, but > an object provided by tkinter that is linked to a GUI object (such as a > Checkbutton), so that when the GUI object changes, the value of the > "variable" changes, and vice versa.) However, I decided that I wanted to > dispense with the variable, if possible. As you found out the hard way, it is possible, but then you dive into the internals of how the widgets work - usually you don't want to know that. Also, this bit differs between Tk and Ttk widgets. > [...] lengthe description of Checkbutton internals In GUI programming, you will meet a bag of concepts that you haven't seen in sequential programming before. To make it worse, every GUI toolkit brings its own new set of concepts to the table. Maybe it is helpful to work through a Tk tutorial first. This is a good one: http://tkdocs.com/tutorial/index.html Similarly to the tutorial I would suggest to stick with the ttk widgets. Those are an "update" (> 10 years ago) to the tk widgets and are supposed to provide sensible defaults matching the users experience with native GUI elements. There are only 3 widgets where you must use a Tk widget, this is Text (for multiline formatted text entry), Canvas (for 2D drawings), and Toplevel (for new windows/ popups etc.) Christian From alicpp at gmail.com Wed May 24 09:37:31 2023 From: alicpp at gmail.com (A KR) Date: Wed, 24 May 2023 06:37:31 -0700 (PDT) Subject: getting rid of the recursion in __getattribute__ Message-ID: <528e330c-52b3-4552-b7d3-15b69b1d6c9bn@googlegroups.com> It is perfectly explained in the standards here [1] saying that: In order to avoid infinite recursion in this method, its implementation should always call the base class method with the same name to access any attributes it needs, for example, object.__getattribute__(self, name). Therefore, I wrote a code following what the standard says: class Sample(): def __init__(self): self.a = -10 def __getattribute__(self, name): if name == 'a': return object.__getattribute__(self, name) raise AttributeError() s = Sample() result = s.a print(result) I did not fall into recursion, and the output was -10 I used here object.__getattribute__(self, name) cause the base class of Sample is object. If I derive the Sample class from another class such as A, I should change object.__getattribute__(self, name) to A.__getattribute__(self, name) as the base class of class Sample is class A. class A: pass class Sample(A): def __init__(self): self.a = -10 def __getattribute__(self, name): if name == 'a': return A.__getattribute__(self, name) raise AttributeError() s = Sample() result = s.a print(result) which gives the same output as expected. No recursion and -10. However, when I try the code without deriving from a class: class AnyClassNoRelation: pass class Sample(): def __init__(self): self.a = -10 def __getattribute__(self, name): if name == 'a': return AnyClassNoRelation.__getattribute__(self, name) raise AttributeError() s = Sample() result = s.a print(result) and calling __getattribute__ via any class (in this example class AnyClassNoRelation) instead of object.__getattribute__(self, name) as the standard says call using the base class, I get the same output: no recursion and -10. So my question: How come this is possible (having the same output without using the base class's __getattribute__? Although the standards clearly states that __getattribute__ should be called from the base class. In order to avoid infinite recursion in this method, its implementation should always call the base class method with the same name to access any attributes it needs, for example, object.__getattribute__(self, name). Literally, I can call __getattribute__ with anyclass (except Sample cause it will be infinite recursion) I define and it works just fine. Could you explain me why that happens? [1] https://docs.python.org/3/reference/datamodel.html#object.__getattribute__ From hjp-python at hjp.at Wed May 24 14:50:35 2023 From: hjp-python at hjp.at (Peter J. Holzer) Date: Wed, 24 May 2023 20:50:35 +0200 Subject: Addition of a .= operator In-Reply-To: References: <435bae66-e0b8-49da-bb39-10606492b59dn@googlegroups.com> <08af3c3a-ba3b-0b15-554e-6ff12cbcf880@btinternet.com> <20230523210326.cxxuju345jkqaqp5@hjp.at> <20230523224638.vigjgnrqqdnmcmvm@hjp.at> Message-ID: <20230524185035.ddle7rlwxubkrw76@hjp.at> On 2023-05-24 08:51:19 +1000, Chris Angelico wrote: > On Wed, 24 May 2023 at 08:48, Peter J. Holzer wrote: > > Yes, that probably wasn't the best example. I sort of deliberately > > avoided method chaining here to make my point that you don't have to > > invent a new variable name for every intermediate result, but of course > > that backfired because in this case you don't need a variable name at > > all. I should have used regular function calls ... > > > > In the context of a .= operator, though, that is *in itself* an > interesting data point: in order to find an example wherein the .= > operator would be plausible, you had to make the .= operator > unnecessary. Another communication failure on my part, I'm afraid: I was going off on a tangent about variable naming and didn't intend to show anything about the usefulness (or lack thereof) of a .= operator. 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 hjp-python at hjp.at Wed May 24 15:09:05 2023 From: hjp-python at hjp.at (Peter J. Holzer) Date: Wed, 24 May 2023 21:09:05 +0200 Subject: OT: Addition of a .= operator In-Reply-To: <7485cf2f-f9ff-7891-024e-b1e395a6bb6a@DancesWithMice.info> References: <435bae66-e0b8-49da-bb39-10606492b59dn@googlegroups.com> <08af3c3a-ba3b-0b15-554e-6ff12cbcf880@btinternet.com> <20230523210326.cxxuju345jkqaqp5@hjp.at> <9d8badab-4af7-8b5b-92a3-2fc7b1ea2fec@btinternet.com> <7485cf2f-f9ff-7891-024e-b1e395a6bb6a@DancesWithMice.info> Message-ID: <20230524190905.u2zu7muewyyzznoc@hjp.at> On 2023-05-24 12:10:09 +1200, dn via Python-list wrote: > Perhaps more psychology rather than coding? Both. As they say, coding means writing for other people first, for the computer second. So that means anticipating what will be least confusing for that other person[1] who's going to read that code. hp [1] Which is often yourself, a few months older. Or it could be an experienced colleague who's very familiar with the codebase. Or a new colleague trying to understand what this is all about (possibly while learning Python). -- _ | 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 cs at cskk.id.au Wed May 24 20:20:31 2023 From: cs at cskk.id.au (Cameron Simpson) Date: Thu, 25 May 2023 10:20:31 +1000 Subject: Tkinter docs? In-Reply-To: References: Message-ID: On 24May2023 02:18, Rob Cliffe wrote: >??? There doesn't seem to be any decent documentation for it anywhere. Already mentioned in the replies, I use this: https://tkdocs.com/shipman/index.html quite a lot. From __peter__ at web.de Thu May 25 03:59:03 2023 From: __peter__ at web.de (Peter Otten) Date: Thu, 25 May 2023 09:59:03 +0200 Subject: getting rid of the recursion in __getattribute__ In-Reply-To: <528e330c-52b3-4552-b7d3-15b69b1d6c9bn@googlegroups.com> References: <528e330c-52b3-4552-b7d3-15b69b1d6c9bn@googlegroups.com> Message-ID: On 24/05/2023 15:37, A KR wrote: > It is perfectly explained in the standards here [1] saying that: > > > In order to avoid infinite recursion in this method, its implementation should always call the base class method with the same name to access any attributes it needs, for example, object.__getattribute__(self, name). > > > Therefore, I wrote a code following what the standard says: > > > class Sample(): > def __init__(self): > self.a = -10 > > def __getattribute__(self, name): > if name == 'a': > return object.__getattribute__(self, name) > > raise AttributeError() > > s = Sample() > result = s.a > print(result) > > I did not fall into recursion, and the output was > -10 While this works it's not how I understand the recommended pattern. I'd rather treat "special" attributes first and then use the __getattribute__ method of the base class as a fallback: >> class Demo: def __getattribute__(self, name): if name == "answer": return 42 return super().__getattribute__(name) That way your special arguments, >>> d = Demo() >>> d.answer 42 missing arguments >>> d.whatever Traceback (most recent call last): File "", line 1, in d.whatever File "", line 5, in __getattribute__ return super().__getattribute__(name) AttributeError: 'Demo' object has no attribute 'whatever' and "normal" arguments are treated as expected >>> d.question = "What's up?" >>> d.question "What's up?" Eventual "special" arguments in the superclass would also remain accessible. > However, when I try the code without deriving from a class: > > class AnyClassNoRelation: > pass > > class Sample(): > def __init__(self): > self.a = -10 > > def __getattribute__(self, name): > if name == 'a': > return AnyClassNoRelation.__getattribute__(self, name) > > raise AttributeError() > > s = Sample() > > result = s.a > print(result) > and calling __getattribute__ via any class (in this example class AnyClassNoRelation) instead of object.__getattribute__(self, name) as the standard says call using the base class, I get the same output: no recursion and -10. > > So my question: > > How come this is possible (having the same output without using the base class's __getattribute__? Although the standards clearly states that __getattribute__ should be called from the base class. AnyClassNoRelation does not override __getattribute__, so >>> AnyClassNoRelation.__getattribute__ is object.__getattribute__ True There is no sanity check whether a method that you call explicitly is actually in an object's inheritance tree, >>> class NoRelation: def __getattribute__(self, name): return name.upper() >>> class Demo: def __getattribute__(self, name): return "<{}>".format(NoRelation.__getattribute__(self, name)) >>> Demo().some_arg '' but the only purpose I can imagine of actually calling "someone else's" method is to confuse the reader... > > In order to avoid infinite recursion in this method, its implementation should always call the base class method with the same name to access any attributes it needs, for example, object.__getattribute__(self, name). > > > Literally, I can call __getattribute__ with anyclass (except Sample cause it will be infinite recursion) I define and it works just fine. Could you explain me why that happens? From robin at reportlab.com Thu May 25 07:23:15 2023 From: robin at reportlab.com (Robin Becker) Date: Thu, 25 May 2023 12:23:15 +0100 Subject: [RELEASE] Python 3.12.0 beta 1 released. In-Reply-To: References: Message-ID: On 22/05/2023 22:04, Thomas Wouters wrote: > I'm pleased to announce the release of Python 3.12 beta 1 (and feature > freeze for Python 3.12). > ....... I see a major difference between 3.12.0a7 and 3.12.0b1 Basically in preppy an importer is defined to handle imports of '.prep' files. This worked as expected in the a7 version and fails in the b1. I put in some prints in the code and I see these calls for the a7 run> $ ~/LOCAL/3.12.0a7/bin/python3 test_import.py > sys.meta_path.insert(.PreppyImporter object at 0x7fa870b84080>) --> [.PreppyImporter object at 0x7fa870b84080>, <_distutils_hack.DistutilsMetaFinder object at 0x7fa871290fb0>, , , ] > PreppyImporter.find_module('sample001',None) > PreppyImporter.load_module('sample001') > 4 > . > ---------------------------------------------------------------------- > Ran 1 test in 0.004s > > OK In 3.12.0b1 although the importer is inserted into sys.meta_path the find_module/load_module methods are never called. and the import fails. So is this an expected change in the way importers behave or a bug? > $ ~/LOCAL/3.12.0b1/bin/python3 test_import.py > sys.meta_path.insert(.PreppyImporter object at 0x7fc866ecb110>) --> [.PreppyImporter object at 0x7fc866ecb110>, , , ] > E > ====================================================================== > ERROR: testImport1 (__main__.ImportTestCase.testImport1) > ---------------------------------------------------------------------- > Traceback (most recent call last): > File "/home/robin/devel/reportlab/REPOS/preppy/tmp/test_import.py", line 13, in testImport1 > import sample001 > ModuleNotFoundError: No module named 'sample001' > > ---------------------------------------------------------------------- > Ran 1 test in 0.001s > > FAILED (errors=1) .......... > Your release team, > Thomas Wouters > Ned Deily > Steve Dower From robin at reportlab.com Thu May 25 07:43:08 2023 From: robin at reportlab.com (Robin Becker) Date: Thu, 25 May 2023 12:43:08 +0100 Subject: [RELEASE] Python 3.12.0 beta 1 released. In-Reply-To: References: Message-ID: <1e6aca43-ca03-0088-2582-2b8c0b4e1f93@everest.reportlab.co.uk> On 25/05/2023 12:23, Robin Becker wrote: > On 22/05/2023 22:04, Thomas Wouters wrote: > > I'm pleased to announce the release of Python 3.12 beta 1 (and feature > > freeze for Python 3.12). > > > ....... > I see a major difference between 3.12.0a7 and 3.12.0b1 > > Basically in preppy an importer is defined to handle imports of '.prep' files. > > This worked as expected in the a7 version and fails in the b1. I put in some prints in the code and I see these calls > for the a7 run> $ ~/LOCAL/3.12.0a7/bin/python3 test_import.py > > sys.meta_path.insert(.PreppyImporter object at 0x7fa870b84080>) --> ......... I think this might be caused by the removal of the find_module method of importlib.abc.MetaPathFinder. So I guess I have to implement a modernised importer. Apologies for noise if that is the case. -- Robin Becker From BlindAnagram at nowhere.org Thu May 25 03:49:06 2023 From: BlindAnagram at nowhere.org (BlindAnagram) Date: Thu, 25 May 2023 08:49:06 +0100 Subject: Does os.path relpath produce an incorrect relative path? Message-ID: I am wondering whether I have misunderstood the semantics of os.path relpath or whether it has a bug. Here is a short test program: ----------------------------------------------------------- from os.path import relpath, split src_path = 'C:\\lib\\src\\' vcx_path = 'C:\\build.vs22\\lib\\lib.vcxproj' rel_path = relpath(src_path, vcx_path) print(f"{vcx_path = }\n{src_path = }\n{rel_path = }\n") vcx_path = 'C:\\build.vs22\\lib\\' rel_path = relpath(src_path, vcx_path) print(f"{vcx_path = }\n{src_path = }\n{rel_path = }\n") vcx_path = 'C:\\build.vs22\\lib\\lib.vcxproj' rel_path = relpath(src_path, split(vcx_path)[0]) print(f"{vcx_path = }\n{src_path = }\n{rel_path = }\n") ----------------------------------------------------------- and its output with Python 3.11: ----------------------------------------------------------- vcx_path = 'C:\\build.vs22\\lib\\lib.vcxproj' src_path = 'C:\\lib\\src\\' rel_path = '..\\..\\..\\lib\\src' vcx_path = 'C:\\build.vs22\\lib\\' src_path = 'C:\\lib\\src\\' rel_path = '..\\..\\lib\\src' vcx_path = 'C:\\build.vs22\\lib\\lib.vcxproj' src_path = 'C:\\lib\\src\\' rel_path = '..\\..\\lib\\src' ----------------------------------------------------------- The first of these three results produces an incorrect relative path because relpath does not strip off any non-directory tails before comparing paths. Is this a bug or my misunderstanding of relpath semantics? Comments would be appreciated as I don't waste developer time if this is not a bug. regards Brian From eryksun at gmail.com Thu May 25 11:53:13 2023 From: eryksun at gmail.com (Eryk Sun) Date: Thu, 25 May 2023 10:53:13 -0500 Subject: Does os.path relpath produce an incorrect relative path? In-Reply-To: References: Message-ID: On 5/25/23, BlindAnagram wrote: > > vcx_path = 'C:\\build.vs22\\lib\\lib.vcxproj' > src_path = 'C:\\lib\\src\\' > rel_path = '..\\..\\..\\lib\\src' > > [snip] > > The first of these three results produces an incorrect relative path > because relpath does not strip off any non-directory tails before > comparing paths. The start path is assumed to be a directory, which defaults to the current working directory, and the input paths are first resolved as absolute paths. In order to reach src_path from vcx_path, one has to traverse 3 levels up to the root directory. https://docs.python.org/3/library/os.path.html#os.path.relpath From greg.ewing at canterbury.ac.nz Thu May 25 12:02:45 2023 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Fri, 26 May 2023 04:02:45 +1200 Subject: Does os.path relpath produce an incorrect relative path? In-Reply-To: References: Message-ID: On 25/05/23 7:49 pm, BlindAnagram wrote: > The first of these three results produces an incorrect relative path > because relpath does not strip off any non-directory tails before > comparing paths. It has no way of knowing whether a pathname component is a directory or not. It's purely an operation on strings, it doesn't look in the file system. -- Greg From python at mrabarnett.plus.com Thu May 25 12:52:01 2023 From: python at mrabarnett.plus.com (MRAB) Date: Thu, 25 May 2023 17:52:01 +0100 Subject: Does os.path relpath produce an incorrect relative path? In-Reply-To: References: Message-ID: <6e32ac60-01f7-1190-16a6-c0ad11f955e8@mrabarnett.plus.com> On 2023-05-25 16:53, Eryk Sun wrote: > On 5/25/23, BlindAnagram wrote: >> >> vcx_path = 'C:\\build.vs22\\lib\\lib.vcxproj' >> src_path = 'C:\\lib\\src\\' >> rel_path = '..\\..\\..\\lib\\src' >> >> [snip] >> >> The first of these three results produces an incorrect relative path >> because relpath does not strip off any non-directory tails before >> comparing paths. > > The start path is assumed to be a directory, which defaults to the > current working directory, and the input paths are first resolved as > absolute paths. In order to reach src_path from vcx_path, one has to > traverse 3 levels up to the root directory. > > https://docs.python.org/3/library/os.path.html#os.path.relpath Well, it's not necessarily the optimal relative path, because it's not always necessary to go all the way up to the root, as in the first example. From kevinmwilson1956 at yahoo.com Thu May 25 17:30:06 2023 From: kevinmwilson1956 at yahoo.com (Kevin M. Wilson) Date: Thu, 25 May 2023 21:30:06 +0000 (UTC) Subject: Invalid literal for int() with base 10? References: <1792304913.2747884.1685050206425.ref@mail.yahoo.com> Message-ID: <1792304913.2747884.1685050206425@mail.yahoo.com> Ok, I'm not finding any info. on the int() for converting a str to an int (that specifies a base parameter)?! The picture is of the code I've written... And the base 10 paradigm involved?? years = int('y') # store for calculationValueError: invalid literal for int() with base 10: 'y'What is meant by "invalid literal"? I'm trying to convert srt to int, and I didn't know I needed to specify the base. Plus I haven't read anything that I need to specify the base for the int(). Attached is the code, showing the code and the execution of said code. "When you pass through the waters, I will be with you: and when you?pass through the rivers, they will not sweep over?you. When?you walk?through the fire, you will not be burned: the flames will not set you ablaze."? ? ? Isaiah 43:2 From kevinmwilson1956 at yahoo.com Thu May 25 19:50:05 2023 From: kevinmwilson1956 at yahoo.com (Kevin M. Wilson) Date: Thu, 25 May 2023 23:50:05 +0000 (UTC) Subject: From geeksforgeeks.org, on converting the string created by the input() to an INT References: <196657712.2815157.1685058605176.ref@mail.yahoo.com> Message-ID: <196657712.2815157.1685058605176@mail.yahoo.com> We can first convert the string representation of float into float using?float()?function and then convert it into an integer using?int().So, why can't a string of an integer be converted to an integer, via?print(int(str('23.5')))??? Perplexed | print(int(float('23.5'))) | "When you pass through the waters, I will be with you: and when you?pass through the rivers, they will not sweep over?you. When?you walk?through the fire, you will not be burned: the flames will not set you ablaze."? ? ? Isaiah 43:2 From rosuav at gmail.com Thu May 25 20:16:54 2023 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 26 May 2023 10:16:54 +1000 Subject: From geeksforgeeks.org, on converting the string created by the input() to an INT In-Reply-To: <196657712.2815157.1685058605176@mail.yahoo.com> References: <196657712.2815157.1685058605176.ref@mail.yahoo.com> <196657712.2815157.1685058605176@mail.yahoo.com> Message-ID: On Fri, 26 May 2023 at 09:58, Kevin M. Wilson via Python-list wrote: > > So, why can't a string of an integer be converted to an integer, via print(int(str('23.5')))??? 23.5 is not an integer, so "23.5" is not the string of an integer. ChrisA From kevinmwilson1956 at yahoo.com Thu May 25 20:22:15 2023 From: kevinmwilson1956 at yahoo.com (Kevin M. Wilson) Date: Fri, 26 May 2023 00:22:15 +0000 (UTC) Subject: Invalid literal for int() with base 10? In-Reply-To: <1792304913.2747884.1685050206425@mail.yahoo.com> References: <1792304913.2747884.1685050206425.ref@mail.yahoo.com> <1792304913.2747884.1685050206425@mail.yahoo.com> Message-ID: <313743561.517468.1685060535527@mail.yahoo.com> Ok, I'm not finding any info. on the int() for converting a str to an int (that specifies a base parameter)?! The picture is of the code I've written... And the base 10 paradigm involved?? years = int('y') # store for calculation ValueError: invalid literal for int() with base 10: 'y' What is meant by "invalid literal"? I'm trying to convert str to int, and I didn't know I needed to specify the base. Plus I haven't read anything that I need to specify the base for the int(). Attached is the code, showing the code and the execution of said code. Sorry, got pissed and didn't check all the content I sent! "When you pass through the waters, I will be with you: and when you?pass through the rivers, they will not sweep over?you. When?you walk?through the fire, you will not be burned: the flames will not set you ablaze."? ? ? Isaiah 43:2 On Thursday, May 25, 2023 at 05:55:06 PM MDT, Kevin M. Wilson via Python-list wrote: Ok, I'm not finding any info. on the int() for converting a str to an int (that specifies a base parameter)?! The picture is of the code I've written... And the base 10 paradigm involved?? years = int('y') # store for calculationValueError: invalid literal for int() with base 10: 'y'What is meant by "invalid literal"? I'm trying to convert srt to int, and I didn't know I needed to specify the base. Plus I haven't read anything that I need to specify the base for the int(). Attached is the code, showing the code and the execution of said code. "When you pass through the waters, I will be with you: and when you?pass through the rivers, they will not sweep over?you. When?you walk?through the fire, you will not be burned: the flames will not set you ablaze."? ? ? Isaiah 43:2 -- https://mail.python.org/mailman/listinfo/python-list From rosuav at gmail.com Thu May 25 20:28:22 2023 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 26 May 2023 10:28:22 +1000 Subject: Invalid literal for int() with base 10? In-Reply-To: <313743561.517468.1685060535527@mail.yahoo.com> References: <1792304913.2747884.1685050206425.ref@mail.yahoo.com> <1792304913.2747884.1685050206425@mail.yahoo.com> <313743561.517468.1685060535527@mail.yahoo.com> Message-ID: On Fri, 26 May 2023 at 10:26, Kevin M. Wilson via Python-list wrote: > > Ok, I'm not finding any info. on the int() for converting a str to an int (that specifies a base parameter)?! The picture is of the code I've written... And the base 10 paradigm involved?? years = int('y') # store for calculation ValueError: invalid literal for int() with base 10: 'y' > Imagine giving this to a human. "How many years did you say?" "Oh, y years." Is that a reasonable way to say a number of years? No. It's an invalid way of specifying a number of years. Python is a little more technical in the way it describes it, but the fact is unchanged. ChrisA From python at mrabarnett.plus.com Thu May 25 21:21:36 2023 From: python at mrabarnett.plus.com (MRAB) Date: Fri, 26 May 2023 02:21:36 +0100 Subject: Invalid literal for int() with base 10? In-Reply-To: <1792304913.2747884.1685050206425@mail.yahoo.com> References: <1792304913.2747884.1685050206425.ref@mail.yahoo.com> <1792304913.2747884.1685050206425@mail.yahoo.com> Message-ID: <80d3dd56-1a3b-ec53-fd75-e05a2649d7a6@mrabarnett.plus.com> On 2023-05-25 22:30, Kevin M. Wilson via Python-list wrote: > Ok, I'm not finding any info. on the int() for converting a str to an int (that specifies a base parameter)?! The picture is of the code I've written... And the base 10 paradigm involved?? years = int('y') # store for calculationValueError: invalid literal for int() with base 10: 'y'What is meant by "invalid literal"? I'm trying to convert srt to int, and I didn't know I needed to specify the base. Plus I haven't read anything that I need to specify the base for the int(). '12' is a string that contains 2 digits, which together represent the number 12. 'y' is a string that contains a letter, which doesn't represent a number. Perhaps what you meant is that y is a variable that contains a string, in which case what you want is int(y). > Attached is the code, showing the code and the execution of said code. There's no code attached; this list automatically strips attachmentments. From grant.b.edwards at gmail.com Thu May 25 21:48:17 2023 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Thu, 25 May 2023 18:48:17 -0700 (PDT) Subject: Invalid literal for int() with base 10? References: <1792304913.2747884.1685050206425.ref@mail.yahoo.com> <1792304913.2747884.1685050206425@mail.yahoo.com> Message-ID: <64700fe1.050a0220.17cdc.101f@mx.google.com> On 2023-05-25, Kevin M. Wilson via Python-list wrote: > Ok, I'm not finding any info. on the int() for converting a str to > an int (that specifies a base parameter)?! Where are you looking? https://docs.python.org/3/library/functions.html#int > The picture is of the code I've written... And the base 10 paradigm > involved?? I've no clue what that sentence means. > years = int('y') # store for calculationValueError: > invalid literal for int() with base 10: 'y'What is meant by "invalid > literal"? It means that the string 'y' isn't an integer literal. The strings '123' and '-4' are integer literals. https://docs.python.org/3/reference/expressions.html?highlight=integer%20literal#literals > I'm trying to convert srt to int, and I didn't know I needed to > specify the base. You don't need to unless you want a base other than 10. > Plus I haven't read anything that I need to specify the base for the int(). Don't know what you mean there. > Attached is the code, showing the code and the execution of said > code. Sorry, I don't see attachments. Include code in posts. > "When you pass through the waters, I will be with you: and > when you?pass through the rivers, they will not sweep > over?you. When?you walk?through the fire, you will not be burned: > the flames will not set you ablaze." Isaiah 43:2 Huh? From Keith.S.Thompson+u at gmail.com Thu May 25 21:33:52 2023 From: Keith.S.Thompson+u at gmail.com (Keith Thompson) Date: Thu, 25 May 2023 18:33:52 -0700 Subject: Invalid literal for int() with base 10? References: <1792304913.2747884.1685050206425.ref@mail.yahoo.com> <1792304913.2747884.1685050206425@mail.yahoo.com> Message-ID: <87edn3zxj3.fsf@nosuchdomain.example.com> "Kevin M. Wilson" writes: > Ok, I'm not finding any info. on the int() for converting a str to an > int (that specifies a base parameter)?! https://docs.python.org/3/library/functions.html#int > The picture is of the code I've written... I don't see a picture. The mailing list probably does not accept attachments. (You don't need a picture anyway.) > And the base 10 paradigm involved?? The int() constructor takes a base parameter whose default value is 10. If you specify base=0, it will accept binary, octal, and hexadecimal numbers in addition to decimal. All this is explained in the link I gave you. > years = int('y') # store for calculationValueError: invalid > literal for int() with base 10: 'y'What is meant by "invalid literal"? '42' is a valid literal for int(). 'y' is not. What value did you expect int('y') to give you? Perhaps you have a variable named 'y' containing a string? If so, you might want something like int(y) or int(f{'y'}), but int('y') passes the literal string 'y', which has nothing to do with a variable of that name. > I'm trying to convert srt to int, Do you mean "str to int"? > and I didn't know I needed to specify the base. You don't. If you don't specify the base, it defaults to 10. > Plus I haven't read anything that I need to specify > the base for the int(). Attached is the code, showing the code and > the execution of said code. Any attachment was removed. > "When you pass through the waters, I will > be with you: and when you?pass through the rivers, they will not sweep > over?you. When?you walk?through the fire, you will not be burned: the > flames will not set you ablaze."? ? ? Isaiah 43:2 You can add a signature to all your messages if you like, but it will be very helpful if you introduce it with a line consisting of "-- ", as I've done here. It would also be very helpful if you introduce line breaks into your message, particularly before and after any included code. The formatting made your message difficult to read. -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u at gmail.com Will write code for food. void Void(void) { Void(); } /* The recursive call of the void */ From roel at roelschroeven.net Fri May 26 03:43:20 2023 From: roel at roelschroeven.net (Roel Schroeven) Date: Fri, 26 May 2023 09:43:20 +0200 Subject: Invalid literal for int() with base 10? In-Reply-To: <1792304913.2747884.1685050206425@mail.yahoo.com> References: <1792304913.2747884.1685050206425.ref@mail.yahoo.com> <1792304913.2747884.1685050206425@mail.yahoo.com> Message-ID: Op 25/05/2023 om 23:30 schreef Kevin M. Wilson via Python-list: > Ok, I'm not finding any info. on the int() for converting a str to an int (that specifies a base parameter)?! The picture is of the code I've written... And the base 10 paradigm involved?? years = int('y') # store for calculationValueError: invalid literal for int() with base 10: 'y'What is meant by "invalid literal"? I'm trying to convert srt to int, and I didn't know I needed to specify the base. Plus I haven't read anything that I need to specify the base for the int(). That error message might give the impression that you have to specify the base, but that's misleading. It's just trying to be helpful, showing what base was used because the allowed values depend on the base. For example, these will work: int('abcd', 16) # abcd is a valid hexadecimal number int('249', 10) int('249') # same as above, since base 10 is the default int('14', 8) These don't work: int('abcd', 10) # abcd is not a decimal number int('abcd') # same as above, since base 10 is the default int('249', 8) # 249 is not an octal number since 9 is not an octal digit An error message like "invalid literal for int(): '249'" would be very confusing because 249 seems to be a valid integer at first sight; ""invalid literal for int(): '249' with base 8" makes clear why it's not accepted. -- "I love science, and it pains me to think that to so many are terrified of the subject or feel that choosing science means you cannot also choose compassion, or the arts, or be awed by nature. Science is not meant to cure us of mystery, but to reinvent and reinvigorate it." -- Robert Sapolsky From roel at roelschroeven.net Fri May 26 03:55:16 2023 From: roel at roelschroeven.net (Roel Schroeven) Date: Fri, 26 May 2023 09:55:16 +0200 Subject: "Invalid literal for int() with base 10": is it really a literal? Message-ID: <582fe74f-9c1d-a6e2-0678-9b171f383c50@roelschroeven.net> Kevin M. Wilson's post "Invalid literal for int() with base 10?" got me thinking about the use of the word "literal" in that message. Is it correct to use "literal" in that context? It's correct in something like this: >>> int('invalid') Traceback (most recent call last): ? File "", line 1, in ValueError: invalid literal for int() with base 10: 'invalid' But something like this generates the same message: >>> int(input()) hello Traceback (most recent call last): ? File "", line 1, in ValueError: invalid literal for int() with base 10: 'hello' In cases like this there is no literal in sight. I'm thinking it would be more correct to use the term 'value' here: ValueError: invalid value for int() with base 10: 'hello' Does my reasoning make sense? -- "I love science, and it pains me to think that to so many are terrified of the subject or feel that choosing science means you cannot also choose compassion, or the arts, or be awed by nature. Science is not meant to cure us of mystery, but to reinvent and reinvigorate it." -- Robert Sapolsky From rosuav at gmail.com Fri May 26 04:29:58 2023 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 26 May 2023 18:29:58 +1000 Subject: "Invalid literal for int() with base 10": is it really a literal? In-Reply-To: <582fe74f-9c1d-a6e2-0678-9b171f383c50@roelschroeven.net> References: <582fe74f-9c1d-a6e2-0678-9b171f383c50@roelschroeven.net> Message-ID: On Fri, 26 May 2023 at 17:56, Roel Schroeven wrote: > > Kevin M. Wilson's post "Invalid literal for int() with base 10?" got me > thinking about the use of the word "literal" in that message. Is it > correct to use "literal" in that context? It's correct in something like > this: > > >>> int('invalid') > Traceback (most recent call last): > File "", line 1, in > ValueError: invalid literal for int() with base 10: 'invalid' > > But something like this generates the same message: > > >>> int(input()) > hello > Traceback (most recent call last): > File "", line 1, in > ValueError: invalid literal for int() with base 10: 'hello' > > In cases like this there is no literal in sight. > > I'm thinking it would be more correct to use the term 'value' here: > ValueError: invalid value for int() with base 10: 'hello' > Does my reasoning make sense? > It's a ValueError, so the problem is with the value. I suppose "invalid notation" might work, but since the definition of what's acceptable to the int() constructor is the same as for a Python literal, it's not wrong to use that word. However, if you want to change the wording, I'd be more inclined to synchronize it with float(): >>> float("a") Traceback (most recent call last): File "", line 1, in ValueError: could not convert string to float: 'a' ChrisA From roel at roelschroeven.net Fri May 26 04:53:03 2023 From: roel at roelschroeven.net (Roel Schroeven) Date: Fri, 26 May 2023 10:53:03 +0200 Subject: "Invalid literal for int() with base 10": is it really a literal? In-Reply-To: References: <582fe74f-9c1d-a6e2-0678-9b171f383c50@roelschroeven.net> Message-ID: <61750a70-b628-3d99-0a1e-74aaa8815559@roelschroeven.net> Op 26/05/2023 om 10:29 schreef Chris Angelico: > However, if you want to change the wording, I'd be more inclined to > synchronize it with float(): > > >>> float("a") > Traceback (most recent call last): > File "", line 1, in > ValueError: could not convert string to float: 'a' > I was looking for other ValueError-generating functions to find potentially better wording, and I somehow failed to think of float(), so thank you for mentioning it :) The ones I could think of were math functions like math.sqrt(); they give "ValueError: math domain error" which is rather less user friendly. -- "'How to Stop Worrying and Learn to Love the Internet': 1) everything that?s already in the world when you?re born is just normal; 2) anything that gets invented between then and before you turn thirty is incredibly exciting and creative and with any luck you can make a career out of it; 3) anything that gets invented after you?re thirty is against the natural order of things and the beginning of the end of civilisation as we know it until it?s been around for about ten years when it gradually turns out to be alright really. Apply this list to movies, rock music, word processors and mobile phones to work out how old you are." -- Douglas Adams From grant.b.edwards at gmail.com Fri May 26 09:11:20 2023 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Fri, 26 May 2023 06:11:20 -0700 (PDT) Subject: Invalid literal for int() with base 10? References: <1792304913.2747884.1685050206425.ref@mail.yahoo.com> <1792304913.2747884.1685050206425@mail.yahoo.com> <64700fe1.050a0220.17cdc.101f@mx.google.com> Message-ID: <6470aff8.050a0220.17cdc.163d@mx.google.com> On 2023-05-26, Grant Edwards wrote: > On 2023-05-25, Kevin M. Wilson via Python-list wrote: > >> Ok, I'm not finding any info. on the int() for converting a str to >> an int (that specifies a base parameter)?! > > Where are you looking? > > https://docs.python.org/3/library/functions.html#int And don't forget about the help() function: $ python Python 3.11.3 (main, May 8 2023, 09:00:58) [GCC 12.2.1 20230428] on linux Type "help", "copyright", "credits" or "license" for more information. >>> >>> help(int) Help on class int in module builtins: class int(object) | int([x]) -> integer | int(x, base=10) -> integer | | Convert a number or string to an integer, or return 0 if no arguments | are given. If x is a number, return x.__int__(). For floating point | numbers, this truncates towards zero. | | If x is not a number or if base is given, then x must be a string, | bytes, or bytearray instance representing an integer literal in the | given base. The literal can be preceded by '+' or '-' and be surrounded | by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. | Base 0 means to interpret the base from the string as an integer literal. | >>> int('0b100', base=0) | 4 | | Built-in subclasses: | bool | | Methods defined here: | | __abs__(self, /) | abs(self) | | __add__(self, value, /) | Return self+value. | [...] From Keith.S.Thompson+u at gmail.com Fri May 26 04:46:09 2023 From: Keith.S.Thompson+u at gmail.com (Keith Thompson) Date: Fri, 26 May 2023 01:46:09 -0700 Subject: Invalid literal for int() with base 10? References: <1792304913.2747884.1685050206425.ref@mail.yahoo.com> <1792304913.2747884.1685050206425@mail.yahoo.com> <87edn3zxj3.fsf@nosuchdomain.example.com> Message-ID: <87wn0vxyy6.fsf@nosuchdomain.example.com> Keith Thompson writes: > "Kevin M. Wilson" writes: >> Ok, I'm not finding any info. on the int() for converting a str to an >> int (that specifies a base parameter)?! > > https://docs.python.org/3/library/functions.html#int [...] Or `print(int.__doc__)` at a Python ">>>" prompt, or `pydoc int` (or `pydoc3 int`) at a shell prompt. The latter may or may not be available. -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u at gmail.com Will write code for food. void Void(void) { Void(); } /* The recursive call of the void */ From riemannic at gmail.com Fri May 26 08:41:14 2023 From: riemannic at gmail.com (cactus) Date: Fri, 26 May 2023 05:41:14 -0700 (PDT) Subject: Does os.path relpath produce an incorrect relative path? In-Reply-To: References: <6e32ac60-01f7-1190-16a6-c0ad11f955e8@mrabarnett.plus.com> Message-ID: <586a888b-f72b-417c-9b9f-6e357a15fbd9n@googlegroups.com> On Thursday, 25 May 2023 at 17:57:21 UTC+1, MRAB wrote: > On 2023-05-25 16:53, Eryk Sun wrote: > > On 5/25/23, BlindAnagram wrote: > >> > >> vcx_path = 'C:\\build.vs22\\lib\\lib.vcxproj' > >> src_path = 'C:\\lib\\src\\' > >> rel_path = '..\\..\\..\\lib\\src' > >> > >> [snip] > >> > >> The first of these three results produces an incorrect relative path > >> because relpath does not strip off any non-directory tails before > >> comparing paths. > > > > The start path is assumed to be a directory, which defaults to the > > current working directory, and the input paths are first resolved as > > absolute paths. In order to reach src_path from vcx_path, one has to > > traverse 3 levels up to the root directory. > > > > https://docs.python.org/3/library/os.path.html#os.path.relpath > Well, it's not necessarily the optimal relative path, because it's not > always necessary to go all the way up to the root, as in the first example. Thanks to all for their comments. I was hoping that there would be an direct way in Python to find a relative path between two paths in which the convention is that all directories end with '\\' so that it is possible to distinguish the 'tail' references to files as not part of the path comparison. But I will just have to remember to strip the file tails myself. Surprisingly (for me at least) the alternative provided by the pathlib module 'relative_to' method doesn't provide for full relative path computation. I was expecting this would offer everything that os.path offers but it doesn't in this case. Brian From eryksun at gmail.com Fri May 26 11:42:01 2023 From: eryksun at gmail.com (Eryk Sun) Date: Fri, 26 May 2023 10:42:01 -0500 Subject: Does os.path relpath produce an incorrect relative path? In-Reply-To: <586a888b-f72b-417c-9b9f-6e357a15fbd9n@googlegroups.com> References: <6e32ac60-01f7-1190-16a6-c0ad11f955e8@mrabarnett.plus.com> <586a888b-f72b-417c-9b9f-6e357a15fbd9n@googlegroups.com> Message-ID: On 5/26/23, cactus wrote: > > Surprisingly (for me at least) the alternative provided by the pathlib > module 'relative_to' method doesn't provide for full relative path > computation. I was expecting this would offer everything that os.path > offers but it doesn't in this case. Starting with Python 3.12, the relative_to() method has a walk_up parameter. It defaults to False for the sake of backward compatibility. https://docs.python.org/3.12/library/pathlib.html#pathlib.PurePath.relative_to From python at mrabarnett.plus.com Fri May 26 11:58:31 2023 From: python at mrabarnett.plus.com (MRAB) Date: Fri, 26 May 2023 16:58:31 +0100 Subject: "Invalid literal for int() with base 10": is it really a literal? In-Reply-To: References: <582fe74f-9c1d-a6e2-0678-9b171f383c50@roelschroeven.net> Message-ID: <08709a75-748f-476c-dcde-43f4599f792a@mrabarnett.plus.com> On 2023-05-26 09:29, Chris Angelico wrote: > On Fri, 26 May 2023 at 17:56, Roel Schroeven wrote: >> >> Kevin M. Wilson's post "Invalid literal for int() with base 10?" got me >> thinking about the use of the word "literal" in that message. Is it >> correct to use "literal" in that context? It's correct in something like >> this: >> >> >>> int('invalid') >> Traceback (most recent call last): >> File "", line 1, in >> ValueError: invalid literal for int() with base 10: 'invalid' >> >> But something like this generates the same message: >> >> >>> int(input()) >> hello >> Traceback (most recent call last): >> File "", line 1, in >> ValueError: invalid literal for int() with base 10: 'hello' >> >> In cases like this there is no literal in sight. >> >> I'm thinking it would be more correct to use the term 'value' here: >> ValueError: invalid value for int() with base 10: 'hello' >> Does my reasoning make sense? >> > > It's a ValueError, so the problem is with the value. I suppose > "invalid notation" might work, but since the definition of what's > acceptable to the int() constructor is the same as for a Python > literal, it's not wrong to use that word. > > However, if you want to change the wording, I'd be more inclined to > synchronize it with float(): > >>>> float("a") > Traceback (most recent call last): > File "", line 1, in > ValueError: could not convert string to float: 'a' > You still need to mention the base because: >>> int('y', 36) 34 From avi.e.gross at gmail.com Fri May 26 12:22:57 2023 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Fri, 26 May 2023 12:22:57 -0400 Subject: "Invalid literal for int() with base 10": is it really a literal? In-Reply-To: <582fe74f-9c1d-a6e2-0678-9b171f383c50@roelschroeven.net> References: <582fe74f-9c1d-a6e2-0678-9b171f383c50@roelschroeven.net> Message-ID: <005901d98fee$555d8140$001883c0$@gmail.com> Roel, In order for the code to provide different error messages, it needs a way to differentiate between circumstances. As far as the int() function is concerned, it sees a string of characters and has no clue where they came from. In Python, int(input()) just runs input() first and creates a string and then passes it along to int(). You can of course argue there are ways to phrase an error message that may be less technicalese. -----Original Message----- From: Python-list On Behalf Of Roel Schroeven Sent: Friday, May 26, 2023 3:55 AM To: python-list at python.org Subject: "Invalid literal for int() with base 10": is it really a literal? Kevin M. Wilson's post "Invalid literal for int() with base 10?" got me thinking about the use of the word "literal" in that message. Is it correct to use "literal" in that context? It's correct in something like this: >>> int('invalid') Traceback (most recent call last): File "", line 1, in ValueError: invalid literal for int() with base 10: 'invalid' But something like this generates the same message: >>> int(input()) hello Traceback (most recent call last): File "", line 1, in ValueError: invalid literal for int() with base 10: 'hello' In cases like this there is no literal in sight. I'm thinking it would be more correct to use the term 'value' here: ValueError: invalid value for int() with base 10: 'hello' Does my reasoning make sense? -- "I love science, and it pains me to think that to so many are terrified of the subject or feel that choosing science means you cannot also choose compassion, or the arts, or be awed by nature. Science is not meant to cure us of mystery, but to reinvent and reinvigorate it." -- Robert Sapolsky -- https://mail.python.org/mailman/listinfo/python-list From giuseppacefalu at gmail.com Fri May 26 20:30:49 2023 From: giuseppacefalu at gmail.com (giuseppacefalu at gmail.com) Date: Fri, 26 May 2023 20:30:49 -0400 Subject: Module error Message-ID: <002e01d99032$7cdcf400$7696dc00$@gmail.com> I have reinstalled python which reinstalls pip. I have added the path:'C:\sers\Giuseppa\AppData\Local\Packages\PythonSoftwareFoundation.Pytho n.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\Scripts and still get the error below. Could you help me with this please? Traceback (most recent call last): File "C:\Users\Giuseppa\Documents\DataScience\PYTHON\Subsetting.py", line 11, in import pandas as pd ModuleNotFoundError: No module named 'pandas' Thank you!No From giuseppacefalu at gmail.com Fri May 26 20:35:14 2023 From: giuseppacefalu at gmail.com (giuseppacefalu at gmail.com) Date: Fri, 26 May 2023 20:35:14 -0400 Subject: FW: Module error In-Reply-To: <002e01d99032$7cdcf400$7696dc00$@gmail.com> References: <002e01d99032$7cdcf400$7696dc00$@gmail.com> Message-ID: <003c01d99033$1acc9fd0$5065df70$@gmail.com> The directory is empty after issuing the command: Directory of C:\Users\Giuseppa\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.1 1_qbz5n2kfra8p0\LocalCache\local-packages\Python311\Scripts 05/26/2023 07:57 PM . 05/26/2023 04:03 PM .. 05/26/2023 04:07 PM 108,469 f2py.exe 05/26/2023 04:03 PM 108,497 normalizer.exe 05/26/2023 07:57 PM 108,474 pip.exe 05/26/2023 07:57 PM 108,474 pip3.11.exe 05/26/2023 07:57 PM 108,474 pip3.exe 5 File(s) 542,388 bytes 2 Dir(s) 378,485,805,056 bytes free From: giuseppacefalu at gmail.com Sent: Friday, May 26, 2023 8:31 PM To: python-list at python.org Subject: Module error I have reinstalled python which reinstalls pip. I have added the path:'C:\sers\Giuseppa\AppData\Local\Packages\PythonSoftwareFoundation.Pytho n.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\Scripts and still get the error below. Could you help me with this please? Traceback (most recent call last): File "C:\Users\Giuseppa\Documents\DataScience\PYTHON\Subsetting.py", line 11, in import pandas as pd ModuleNotFoundError: No module named 'pandas' Thank you!No From giuseppacefalu at gmail.com Fri May 26 20:35:51 2023 From: giuseppacefalu at gmail.com (giuseppacefalu at gmail.com) Date: Fri, 26 May 2023 20:35:51 -0400 Subject: FW: Module error In-Reply-To: <002e01d99032$7cdcf400$7696dc00$@gmail.com> References: <002e01d99032$7cdcf400$7696dc00$@gmail.com> Message-ID: <004a01d99033$307fbd30$917f3790$@gmail.com> Directory of C:\Users\Giuseppa\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.1 1_qbz5n2kfra8p0\LocalCache\local-packages\Python311\Scripts 05/26/2023 07:57 PM . 05/26/2023 04:03 PM .. 05/26/2023 04:07 PM 108,469 f2py.exe 05/26/2023 04:03 PM 108,497 normalizer.exe 05/26/2023 07:57 PM 108,474 pip.exe 05/26/2023 07:57 PM 108,474 pip3.11.exe 05/26/2023 07:57 PM 108,474 pip3.exe 5 File(s) 542,388 bytes 2 Dir(s) 378,485,805,056 bytes free From: giuseppacefalu at gmail.com Sent: Friday, May 26, 2023 8:31 PM To: python-list at python.org Subject: Module error I have reinstalled python which reinstalls pip. I have added the path:'C:\sers\Giuseppa\AppData\Local\Packages\PythonSoftwareFoundation.Pytho n.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\Scripts and still get the error below. Could you help me with this please? Traceback (most recent call last): File "C:\Users\Giuseppa\Documents\DataScience\PYTHON\Subsetting.py", line 11, in import pandas as pd ModuleNotFoundError: No module named 'pandas' Thank you!No From python at mrabarnett.plus.com Fri May 26 22:37:47 2023 From: python at mrabarnett.plus.com (MRAB) Date: Sat, 27 May 2023 03:37:47 +0100 Subject: Module error In-Reply-To: <002e01d99032$7cdcf400$7696dc00$@gmail.com> References: <002e01d99032$7cdcf400$7696dc00$@gmail.com> Message-ID: <0f546911-ff75-20b3-c70c-d116775a56f6@mrabarnett.plus.com> On 2023-05-27 01:30, giuseppacefalu at gmail.com wrote: > I have reinstalled python which reinstalls pip. I have added the > path:'C:\sers\Giuseppa\AppData\Local\Packages\PythonSoftwareFoundation.Pytho > n.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\Scripts and still > get the error below. Could you help me with this please? > > > > Traceback (most recent call last): > > File "C:\Users\Giuseppa\Documents\DataScience\PYTHON\Subsetting.py", line > 11, in > > import pandas as pd > > ModuleNotFoundError: No module named 'pandas' > Have you tried re-installing pandas? From dieter at handshake.de Sat May 27 00:29:14 2023 From: dieter at handshake.de (Dieter Maurer) Date: Sat, 27 May 2023 06:29:14 +0200 Subject: "Invalid literal for int() with base 10": is it really a literal? In-Reply-To: References: <582fe74f-9c1d-a6e2-0678-9b171f383c50@roelschroeven.net> Message-ID: <25713.34586.318574.504057@ixdm.fritz.box> Chris Angelico wrote at 2023-5-26 18:29 +1000: > ... >However, if you want to change the wording, I'd be more inclined to >synchronize it with float(): > >>>> float("a") >Traceback (most recent call last): > File "", line 1, in >ValueError: could not convert string to float: 'a' +1 From list1 at tompassin.net Fri May 26 23:49:01 2023 From: list1 at tompassin.net (Thomas Passin) Date: Fri, 26 May 2023 23:49:01 -0400 Subject: Module error In-Reply-To: <002e01d99032$7cdcf400$7696dc00$@gmail.com> References: <002e01d99032$7cdcf400$7696dc00$@gmail.com> Message-ID: <0f2343f4-1a21-af99-240f-78066043f576@tompassin.net> On 5/26/2023 8:30 PM, giuseppacefalu at gmail.com wrote: > I have reinstalled python which reinstalls pip. I have added the > path:'C:\sers\Giuseppa\AppData\Local\Packages\PythonSoftwareFoundation.Pytho > n.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\Scripts and still > get the error below. Could you help me with this please? > > > > Traceback (most recent call last): > > File "C:\Users\Giuseppa\Documents\DataScience\PYTHON\Subsetting.py", line > 11, in > > import pandas as pd > > ModuleNotFoundError: No module named 'pandas' First of all, did you install Python from the Microsoft Store or using the Python installer from python.org? The python.org installer does not use paths like that. In case of problems, I think it would be preferable to install using the python.org installer. Second, after an install of Python, you need to install any packages that are not standard Python modules and libraries. Pandas is not part of a standard Python installation, so you would have to re-install it. Changing the Windows path has nothing to do with it. Install pandas with -m pip install pandas --user where is the actual command that you use to run the version of Python you want to work with. You can find out if your version of Python is running out of that LocalCache directory or not by running the following from the command line in a console: -c "import sys;print('\n'.join(sys.path))" Again, represents your actual "python" command. You will get a display something like mine (I'm not showing the entire listing): C:\Users\tom\AppData\Local\Programs\Python\Python311\python311.zip C:\Users\tom\AppData\Local\Programs\Python\Python311\DLLs C:\Users\tom\AppData\Local\Programs\Python\Python311\Lib C:\Users\tom\AppData\Local\Programs\Python\Python311 C:\Users\tom\AppData\Roaming\Python\Python311\site-packages You see that in my case, there is no LocalCache directory involved. I installed using the installer from python.org. From BlindAnagram at nowhere.org Sat May 27 05:21:34 2023 From: BlindAnagram at nowhere.org (BlindAnagram) Date: Sat, 27 May 2023 10:21:34 +0100 Subject: Does os.path relpath produce an incorrect relative path? In-Reply-To: References: <6e32ac60-01f7-1190-16a6-c0ad11f955e8@mrabarnett.plus.com> <586a888b-f72b-417c-9b9f-6e357a15fbd9n@googlegroups.com> Message-ID: On 26/05/2023 16:42, Eryk Sun wrote: > On 5/26/23, cactus wrote: >> >> Surprisingly (for me at least) the alternative provided by the pathlib >> module 'relative_to' method doesn't provide for full relative path >> computation. I was expecting this would offer everything that os.path >> offers but it doesn't in this case. > > Starting with Python 3.12, the relative_to() method has a walk_up > parameter. It defaults to False for the sake of backward > compatibility. > > https://docs.python.org/3.12/library/pathlib.html#pathlib.PurePath.relative_to Thanks, it is good to know that this is coming. Brian From rob.cliffe at btinternet.com Fri May 26 11:41:31 2023 From: rob.cliffe at btinternet.com (Rob Cliffe) Date: Fri, 26 May 2023 16:41:31 +0100 Subject: Tkinter docs? In-Reply-To: <646d83e0.050a0220.5128f.338f@mx.google.com> References: <646d83e0.050a0220.5128f.338f@mx.google.com> Message-ID: <6f8e8ecc-4046-da2d-5454-5aee86b06e0f@btinternet.com> Thanks to everyone who replied.? All replies were constructive, none were telling me to stop belly-aching. I forgot/omitted to state that it was I who wrote the original project (in a completely different language), making the task of re-writing it much less formidable.? And meaning that I am familiar with the general concepts of building a GUI.? Still, it will be a lot of work. Grant, I may well buy one of the books you suggested. I find the topic of themes and styles the hardest one to get my head around (if anyone knows a good introduction that would be fantastic).? All the other stuff is OK provided I can find something on the net to give me the necessary information, which so far I usually can. Christian, I am adopting your suggestion of using ttk widgets, except for Button objects, because ??? The colour of tk.Button objects can be set directly (bg=... fg=...) ??? On my platform (Windows10) the shadowing of tk.Button objects is more conspicuous (without using styles or whatever). Best wishes Rob Cliffe From jschaffler at proton.me Sun May 28 16:10:02 2023 From: jschaffler at proton.me (James Schaffler) Date: Sun, 28 May 2023 20:10:02 +0000 Subject: Why does IDLE use a subprocess? Message-ID: <0yjTTMo6f2sNAeHM8DWbLsJ3Yh3N1Fc-9MUmGXN4PoQ7rh3ovCCCEDrEb-UkCDWxIfwO1KaLP8WS2QMGtWz7phfJOU4rH-uhW5X8Wov-xEU=@proton.me> Originally posted to idle-dev, but thought this might be a better place. Let me know if it isn't. Hi, I was curious about the internals of IDLE, and noticed that IDLE uses executes user code in a "subprocess" that's separate from the Python interpreter that is running IDLE itself (which does tasks such as making the window and coloring the text). As far as I understand, IDLE runs a modified version of code.InteractiveInterpreter by sending user code through a socket. Even the IDLE documentation says that without a subprocess, "user code is not isolated from IDLE itself." However, some minimal testing of InteractiveInterpreter leads me to believe that the Interpreter object has its own view of local/global variables and therefore shouldn't be able to affect the calling interpreter (please correct me if I'm wrong). So my question is a combination of "Why does IDLE use a subprocess?" and "Why is InteractiveInterpreter not secure enough?" What possible security vulnerabilities exist if one uses IDLE without the subprocess? If anyone knows (or could point me to information on) why IDLE is designed this way, I'd really appreciate it. Thank you! Jim From d.danielife at gmail.com Tue May 30 10:40:46 2023 From: d.danielife at gmail.com (Daniel Ifechukwude Dibie) Date: Tue, 30 May 2023 15:40:46 +0100 Subject: complaint Message-ID: i tried to uninstall the python 3.11.3 program from my machine so that i can re-install it is showing successful but it is ligerning on the program and features From dalton at nfld.com Sun May 28 02:33:57 2023 From: dalton at nfld.com (David Dalton) Date: Sun, 28 May 2023 04:03:57 -0230 Subject: wordplay References: Message-ID: In article , David Dalton wrote: > cODINg :-) Since Odin is described as the Sky Father, I think he is the one I call Cosma, not the one I call Gwydion or the avatar type who was the author of Havamal 138--141. c I take to represent light. g I take to represent gravity. -- https://www.nfld.com/~dalton/dtales.html Salmon on the Thorns (mystic page) "This could be the final breath; This is life and death; This is hard rock and water; Out here between wind and flame; Between tears and elation; Lies a secret nation" (Ron Hynes) From chris.m.thomasson.1 at gmail.com Sun May 28 02:35:27 2023 From: chris.m.thomasson.1 at gmail.com (Chris M. Thomasson) Date: Sat, 27 May 2023 23:35:27 -0700 Subject: wordplay In-Reply-To: References: Message-ID: On 5/26/2023 12:13 AM, David Dalton wrote: > cODINg :-) > Play with the Chaos PP lib... ;^) From dankolis at gmail.com Tue May 30 13:48:41 2023 From: dankolis at gmail.com (Dan Kolis) Date: Tue, 30 May 2023 10:48:41 -0700 (PDT) Subject: Tkinter Redo's In-Reply-To: References: <6f8e8ecc-4046-da2d-5454-5aee86b06e0f@btinternet.com> <646d83e0.050a0220.5128f.338f@mx.google.com> Message-ID: <658f352c-3d0f-4f8f-94e8-f5d8fdc0c87an@googlegroups.com> On Tuesday, May 30, 2023 at 1:28:04?PM UTC-4, Rob Cliffe wrote: > Thanks to everyone who replied. All replies were constructive, none > were telling me to stop belly-aching. Hi, Dan says: When you get your style ideas sort of frozen, maybe you can poke up a sample here. Aworked example for yourself is useful anyway. My stuffs all in Ubuntu so seeing what works and doesn't in MS products interests me a lot. I usually avoid the tkk variations almost completely. I have all the things I use each wrapped in a call that does what I want both aesthetically and so on. My app is only medium sensitive to art look and feel, productivity to maintain it is more important then super fancy looking. Regards, Dan From grant.b.edwards at gmail.com Tue May 30 14:05:16 2023 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Tue, 30 May 2023 11:05:16 -0700 (PDT) Subject: Tkinter docs? References: <646d83e0.050a0220.5128f.338f@mx.google.com> <6f8e8ecc-4046-da2d-5454-5aee86b06e0f@btinternet.com> Message-ID: <64763adc.050a0220.65498.1522@mx.google.com> On 2023-05-26, Rob Cliffe via Python-list wrote: > Grant, I may well buy one of the books you suggested. I haven't had look at either of the newer books, but I got a lot of good out of the Grayson book (20 years ago). I also had a Tcl/Tk book that I found useful even when usng tkinter, but it's even older than the Grayson one... From PythonList at DancesWithMice.info Tue May 30 16:42:41 2023 From: PythonList at DancesWithMice.info (dn) Date: Wed, 31 May 2023 08:42:41 +1200 Subject: complaint In-Reply-To: References: Message-ID: <9fa202ca-3da6-bfd4-ba80-c371113444cd@DancesWithMice.info> Hi Daniel, On 31/05/2023 02.40, Daniel Ifechukwude Dibie wrote: > i tried to uninstall the python 3.11.3 program from my machine so that i > can re-install it is showing successful but it is ligerning on the program > and features Is that word "lingering". If so, do you mean that Python did not uninstall properly - or do you mean that the reinstalled version is slow to operate? Not understanding the question, I threw it into ChatGPT:- User i tried to uninstall the python 3.11.3 program from my machine so that i can re-install it is showing successful but it is ligerning on the program and features ChatGPT If you are experiencing issues uninstalling Python 3.11.3 from your machine, here are a few steps you can try to resolve the problem: Restart your computer: Sometimes, a simple restart can help resolve issues related to the uninstallation process. Use an uninstaller tool: You can try using a third-party uninstaller tool to remove Python 3.11.3 from your system. These tools are designed to thoroughly remove programs, including any leftover files or registry entries. Some popular uninstaller tools include Revo Uninstaller, IObit Uninstaller, and Geek Uninstaller. Manual uninstallation: If the above steps don't work, you can try manually uninstalling Python 3.11.3. Here's how you can do it: Open the "Programs and Features" or "Apps & Features" section in your computer's control panel. Locate Python 3.11.3 in the list of installed programs. Click on Python 3.11.3 and select the "Uninstall" or "Remove" option. Follow the on-screen instructions to complete the uninstallation process. After the uninstallation is complete, you may also want to delete any remaining Python-related folders or files from your system. These are typically located in the "C:\Python3.11" directory. Please note that manually deleting files from your system can be risky if you're not familiar with the process. Be cautious and ensure that you're deleting the correct files associated with Python 3.11.3. Once you have successfully uninstalled Python 3.11.3, you can proceed with reinstalling it on your machine. Make sure to download the installer from the official Python website (https://www.python.org) and follow the installation instructions provided. User i tried to uninstall the python 3.11.3 program from my machine so that i can re-install it is showing successful but it is slow to load the program and features ChatGPT If the uninstallation process appears to be successful, but you are experiencing slow loading of the "Programs and Features" section in the control panel, there might be a few possible reasons for this issue. Here are some steps you can take to troubleshoot the problem: Wait for a while: Sometimes, the uninstallation process might take some time to complete all the necessary tasks, especially if it's a large program like Python. It's possible that the program is still finalizing its uninstallation in the background. Give it some time and see if the "Programs and Features" section starts responding normally after a few minutes. Restart your computer: Restarting your computer can help resolve any lingering processes or system issues that may be causing the slow loading of the "Programs and Features" section. After restarting, try accessing the control panel again and see if the problem persists. Check for other processes or services: It's possible that other processes or services running on your computer are causing a slowdown. Close any unnecessary applications and check if there are any resource-intensive processes running in the background. You can open the Task Manager (Ctrl+Shift+Esc) to check for any unusually high CPU or memory usage. Check for system errors: Run a scan for system errors using the built-in Windows System File Checker (SFC) tool. Open a Command Prompt as an administrator and run the command: sfc /scannow. This will scan your system for any corrupted or missing system files and attempt to repair them. Reinstall Python: If the issue persists, you can try reinstalling Python 3.11.3 again after performing the above steps. Make sure to follow the official installation instructions and download the installer from the official Python website (https://www.python.org). If none of the above steps resolve the slow loading issue, there might be underlying system issues causing the problem. You may consider seeking further assistance from a technical expert or your system administrator to diagnose and resolve the issue. NB I do not use MS-Windows (which is an assumption - not stated in OP), and thus cannot vouch for the veracity of this advice, nor for its accuracy - caveat emptor! Hope one of those sets of ideas will help... - will be interested to hear how you get on... -- Regards, =dn From aapost at idontexist.club Tue May 30 16:44:59 2023 From: aapost at idontexist.club (aapost) Date: Tue, 30 May 2023 16:44:59 -0400 Subject: What to use instead of nntplib? In-Reply-To: References: <469aa006-40d4-38c8-5776-fe0f9e908cf1@yahoo.co.uk> <960340a9-2f55-9e48-4bb3-b39352387935@gmail.com> <6463862f.020a0220.21ee1.48db@mx.google.com> <20230521071044.6879162343f314b305574d14@amongus.com> <646b93dd.050a0220.84d1.18db@mx.google.com> Message-ID: On 5/22/23 12:10, Grant Edwards wrote: > On 2023-05-21, Retrograde wrote: > >> Who ever came up with "Removing dead batteries" as a slogan, when >> some of those batteries still work perfectly well, needs to rethink >> it. Go ahead and remove code that no longer works, OK. But removing >> unpopular modules? That undercuts the entire philosophy of the >> platform, in my opinion. > > And one of the metrics of "popularity" seems to be "activity" > (e.g. changes committed). For things that have been around for 20+ > years and have all the features they need and all of the bugs fixed > (and are now very stable) that lack of "activity" is interpreted as > "unpopular" regardless of how many people are using the module. > > -- > Grant > To add an additional bitching, I don't really ever see anyone discussing the dynamics and downsides of github (and things like it). Or how things like mozilla killing off usenet and mailing lists changes the entire dynamic of who manages and gets a say in how technology gets to move forward. As someone who sees software independence and using free software as moral imperatives, signing up for github and agreeing to yet another terms of service is a no go for me, so moving to these platforms locks me out from contributing. (and a lot of python packages have code that also works with proprietary operating systems, so non-gnu/gnu hosting isn't a solution either) And as someone who uses usenet to post to this list (I object to the google captcha on the mailing list sign up, and captchas in general), I imagine eventually a discussion will take place in a place like github that will do away with this avenue as well. As far as modern commit dynamics, Even if I did partake in the modern github style of code distribution, how many packages have issues where the "maintainers" inherited the package and really haven't dug deep enough in to the code to see how it really works. They have issues that sit around for YEARS, and when someone says "this sucks, this is broken and could be better", and the githubian response is typically a dismissive "Nothing is stopping you from making a PR". Then when you get down to dedicating a month to polishing a PR to extend or redesign something with the features you need, it just sits there, for YEARS, because again, the authority that went in to the package in the first place is often gone, and there is no one with that knowledge to give the PR the review it deserves. You end up with your fork, but it is lost, indistinguished from all the other forks of nothing. There are now probably dozens of nntplib preservation implementations floating around, but how do you even consider which one to use? Without some energy behind it, to be certain in what you are doing, each person will practically have to download Python3.11 and extract it themselves, and then either add it in to the latest version themselves, or comparitively study it vs a collection of new implementations to see which one feels most like a correct updated standard. You also have to consider, is this a one off update? At 3.13 will I have to do it all over again? (at that point, doing it yourself really does become the only solution). At the end of the day, what is there boils down to the influence of who is offering the resources.. And I would say most of that today comes from the microsofts and googles of the world that have no interest in preserving the independent ethos of the early web.. I personally am partial to autonomous website distribution, and mailmanv2 dev collaborations, so you can independently share modified versions of packages or tutorials you've written for your own purposes, and if they help others, great.. But I personally haven't found a place that accepts small cash payments and feels neutral enough to fit my needs and limited resources. From rosuav at gmail.com Tue May 30 17:12:43 2023 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 31 May 2023 07:12:43 +1000 Subject: What to use instead of nntplib? In-Reply-To: References: <469aa006-40d4-38c8-5776-fe0f9e908cf1@yahoo.co.uk> <960340a9-2f55-9e48-4bb3-b39352387935@gmail.com> <6463862f.020a0220.21ee1.48db@mx.google.com> <20230521071044.6879162343f314b305574d14@amongus.com> <646b93dd.050a0220.84d1.18db@mx.google.com> Message-ID: On Wed, 31 May 2023 at 06:59, aapost wrote: > > To add an additional bitching, I don't really ever see anyone discussing > the dynamics and downsides of github (and things like it). Or how things > like mozilla killing off usenet and mailing lists changes the entire > dynamic of who manages and gets a say in how technology gets to move > forward. > I used to run my own mail server. Now I don't. Practicality beats purity. To be quite frank, the moralistic approach of complaining about the way other people are too happy to give control to big companies is NEVER going to achieve anything. You're welcome to be a little island, that one Gaulish village that still holds out against the invaders, but all you'll actually be doing is sidelining yourself. I'm not saying that this is a GOOD situation, but facts are facts, and I use Chrome and GitHub and a wide variety of other tools that aren't free. ChrisA From mats at wichmann.us Tue May 30 17:13:34 2023 From: mats at wichmann.us (Mats Wichmann) Date: Tue, 30 May 2023 15:13:34 -0600 Subject: What to use instead of nntplib? In-Reply-To: <646c01db.920a0220.78995.1ea5@mx.google.com> References: <469aa006-40d4-38c8-5776-fe0f9e908cf1@yahoo.co.uk> <960340a9-2f55-9e48-4bb3-b39352387935@gmail.com> <6463862f.020a0220.21ee1.48db@mx.google.com> <20230521071044.6879162343f314b305574d14@amongus.com> <646b93dd.050a0220.84d1.18db@mx.google.com> <875y8k0zpp.fsf@nosuchdomain.example.com> <646c01db.920a0220.78995.1ea5@mx.google.com> Message-ID: On 5/22/23 17:59, Grant Edwards wrote: > On 2023-05-22, Keith Thompson wrote: > >> My understanding is that nntplib isn't being erased from reality, >> it's merely being removed from the set of modules that are provided >> by default. >> >> I presume that once it's removed from the core, it will still be >> possible to install it via pip or some other mechanism. > > If somebody rescues the code and puts it in Pypi (assuming the > copyright owner allows that). IIRC, somebody is trying to do that, but > there some contention because Pypi won't allow the use of the name > "nntplib" for the package because it conflicts with a library builtin. well, it turns out that while there was a long debate about the merits, the actual request to free up the previously blocked name on PyPI was granted rather quickly, and it's there: https://pypi.org/project/nntplib/ From aapost at idontexist.club Tue May 30 17:40:13 2023 From: aapost at idontexist.club (aapost) Date: Tue, 30 May 2023 17:40:13 -0400 Subject: What to use instead of nntplib? In-Reply-To: References: <469aa006-40d4-38c8-5776-fe0f9e908cf1@yahoo.co.uk> <960340a9-2f55-9e48-4bb3-b39352387935@gmail.com> <6463862f.020a0220.21ee1.48db@mx.google.com> <20230521071044.6879162343f314b305574d14@amongus.com> <646b93dd.050a0220.84d1.18db@mx.google.com> Message-ID: > > I used to run my own mail server. > > Now I don't. > > Practicality beats purity. > > To be quite frank, the moralistic approach of complaining about the > way other people are too happy to give control to big companies is > NEVER going to achieve anything. You're welcome to be a little island, > that one Gaulish village that still holds out against the invaders, > but all you'll actually be doing is sidelining yourself. > > I'm not saying that this is a GOOD situation, but facts are facts, and > I use Chrome and GitHub and a wide variety of other tools that aren't > free. > > ChrisA Don't get me wrong, I know I have lost the battle in this age, lol. The opening statement probably came off way less pragmatic than I intended before writing it. The attempt to steer the ol' "bitching just to bitch" toward more if a statement as to the fundamentals of why there is a bitch and frustration with how things are didn't quite make it there. But regardless my positions are correct, lol, you know the situation is "NOT" GOOD, and you justify your compromises, as we tend to do to whatever extent we decide that we can live with, and time tells how those things play out. For there to have been an elicited reaction to my statements sort of goes against the statement "NEVER going to achieve anything". I am fine in my cave, a lot of things seen as "facts are facts" tend to change over time, and I don't see anyone else going anywhere that I need to go. From barry at barrys-emacs.org Tue May 30 18:15:10 2023 From: barry at barrys-emacs.org (Barry) Date: Tue, 30 May 2023 23:15:10 +0100 Subject: Why does IDLE use a subprocess? In-Reply-To: <0yjTTMo6f2sNAeHM8DWbLsJ3Yh3N1Fc-9MUmGXN4PoQ7rh3ovCCCEDrEb-UkCDWxIfwO1KaLP8WS2QMGtWz7phfJOU4rH-uhW5X8Wov-xEU=@proton.me> References: <0yjTTMo6f2sNAeHM8DWbLsJ3Yh3N1Fc-9MUmGXN4PoQ7rh3ovCCCEDrEb-UkCDWxIfwO1KaLP8WS2QMGtWz7phfJOU4rH-uhW5X8Wov-xEU=@proton.me> Message-ID: > On 30 May 2023, at 21:10, James Schaffler via Python-list wrote: > > ?Originally posted to idle-dev, but thought this might be a better place. Let me know if it isn't. > > Hi, > > I was curious about the internals of IDLE, and noticed that IDLE uses executes user code in a "subprocess" that's separate from the Python interpreter that is running IDLE itself (which does tasks such as making the window and coloring the text). > > As far as I understand, IDLE runs a modified version of code.InteractiveInterpreter by sending user code through a socket. Even the IDLE documentation says that without a subprocess, "user code is not isolated from IDLE itself." However, some minimal testing of InteractiveInterpreter leads me to believe that the Interpreter object has its own view of local/global variables and therefore shouldn't be able to affect the calling interpreter (please correct me if I'm wrong). > > So my question is a combination of "Why does IDLE use a subprocess?" and "Why is InteractiveInterpreter not secureuldenough?" What possible security vulnerabilities exist if one uses IDLE without the subprocess? If anyone knows (or could point me to information on) why IDLE is designed this way, I'd really appreciate it. Thank you! I don?t think it security but robustness that needs the subprocess. You can crash idle with bugs in the code that you are developing. By running your code in a subprocess idle protects itself, and your edits from bugs in your code. Also if your code use tk then it would conflict with idle?s use of tk. That is my assumption on why the subprocess is required. Barry > > Jim > -- > https://mail.python.org/mailman/listinfo/python-list > From barry at barrys-emacs.org Tue May 30 18:20:32 2023 From: barry at barrys-emacs.org (Barry) Date: Tue, 30 May 2023 23:20:32 +0100 Subject: complaint In-Reply-To: References: Message-ID: <636FEE32-0151-46EA-AB12-BAB742ED167B@barrys-emacs.org> > On 30 May 2023, at 21:10, Daniel Ifechukwude Dibie wrote: > > ?i tried to uninstall the python 3.11.3 program from my machine so that i > can re-install it is showing successful but it is ligerning on the program > and features Maybe what you are seeing is the microsoft app store stubs for python? The python.org uninstall always works in my experience, but is not related to the app store stubs. Also why do you think you need to reinstall python? It would be very unusual that that would be necessary. Barry > -- > https://mail.python.org/mailman/listinfo/python-list > From rosuav at gmail.com Tue May 30 18:32:42 2023 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 31 May 2023 08:32:42 +1000 Subject: Why does IDLE use a subprocess? In-Reply-To: References: <0yjTTMo6f2sNAeHM8DWbLsJ3Yh3N1Fc-9MUmGXN4PoQ7rh3ovCCCEDrEb-UkCDWxIfwO1KaLP8WS2QMGtWz7phfJOU4rH-uhW5X8Wov-xEU=@proton.me> Message-ID: On Wed, 31 May 2023 at 08:16, Barry wrote: > I don?t think it security but robustness that needs the subprocess. > > Also if your code use tk then it would conflict with idle?s use of tk. > >From my memory, it's precisely this - it's much MUCH easier to allow you to use Tk in your own program without conflicting with Idle's own use of it. I'm sure it would be possible to make everything work in one process, but the cost of doing so would be greater than the costs of juggling two processes. ChrisA From greg.ewing at canterbury.ac.nz Tue May 30 20:06:41 2023 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Wed, 31 May 2023 12:06:41 +1200 Subject: What to use instead of nntplib? In-Reply-To: References: <469aa006-40d4-38c8-5776-fe0f9e908cf1@yahoo.co.uk> <960340a9-2f55-9e48-4bb3-b39352387935@gmail.com> <6463862f.020a0220.21ee1.48db@mx.google.com> <20230521071044.6879162343f314b305574d14@amongus.com> <646b93dd.050a0220.84d1.18db@mx.google.com> Message-ID: On 31/05/23 8:44 am, aapost wrote: > Even if I did partake in the modern github style of code distribution, > how many packages have issues where the "maintainers" inherited the > package and really haven't dug deep enough in to the code to see how it > really works. They have issues that sit around for YEARS, and when > someone says "this sucks, this is broken and could be better", and the > githubian response is typically a dismissive "Nothing is stopping you > from making a PR". Also, "nothing is stopping you from making a fork." Which is what you would have to do in the face of inactive maintainers regardless of where or how the project was hosted. This is not a github problem or a big-corporation problem, it's a people problem. -- Greg From greg.ewing at canterbury.ac.nz Tue May 30 21:14:40 2023 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Wed, 31 May 2023 13:14:40 +1200 Subject: Why does IDLE use a subprocess? In-Reply-To: References: <0yjTTMo6f2sNAeHM8DWbLsJ3Yh3N1Fc-9MUmGXN4PoQ7rh3ovCCCEDrEb-UkCDWxIfwO1KaLP8WS2QMGtWz7phfJOU4rH-uhW5X8Wov-xEU=@proton.me> Message-ID: On 29/05/23 8:10 am, James Schaffler wrote: > However, some minimal testing of InteractiveInterpreter leads me to believe that the Interpreter object has its own view of local/global variables and therefore shouldn't be able to affect the calling interpreter Globals you create by executing code in the REPL have their own namespace. But everything else is shared -- builtins, imported Python modules, imported C extension modules, etc. etc. There's a long-running project to make it possible to have multiple fully-isolated Python interpreters in one process, but the way CPython is structured makes that very difficult to achieve, and as far as I know it's not there yet. In the case of IDLE, there's really no reason not to use a subprocess[1]. It's easy and guarantees 100% isolation. [1] Well, mostly. There used to be a small hitch on Windows with the default firewall settings not letting you connect to a local socket (nice one, Microsoft). I don't know whether that's still an issue. -- Greg From jschaffler at proton.me Tue May 30 22:01:25 2023 From: jschaffler at proton.me (James Schaffler) Date: Wed, 31 May 2023 02:01:25 +0000 Subject: Why does IDLE use a subprocess? In-Reply-To: References: <0yjTTMo6f2sNAeHM8DWbLsJ3Yh3N1Fc-9MUmGXN4PoQ7rh3ovCCCEDrEb-UkCDWxIfwO1KaLP8WS2QMGtWz7phfJOU4rH-uhW5X8Wov-xEU=@proton.me> Message-ID: On Tuesday, May 30th, 2023 at 9:14 PM, Greg Ewing wrote: > Globals you create by executing code in the REPL have their own > namespace. But everything else is shared -- builtins, imported > Python modules, imported C extension modules, etc. etc. Thanks for the explanation. Could you elaborate on precisely how "everything else is shared"? As far as I understand, if you run the following code: from code import InteractiveInterpreter interp = InteractiveInterpreter() import numpy as np interp.runcode("np.__name__") this will result in the error Traceback (most recent call last): File "", line 1, in NameError: name 'np' is not defined which seems to imply that imports in the parent shell are not shared with interpreters and vice versa (if you swap the places of the import and the __name__ call). Thanks, Jim From rosuav at gmail.com Tue May 30 22:18:23 2023 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 31 May 2023 12:18:23 +1000 Subject: Why does IDLE use a subprocess? In-Reply-To: References: <0yjTTMo6f2sNAeHM8DWbLsJ3Yh3N1Fc-9MUmGXN4PoQ7rh3ovCCCEDrEb-UkCDWxIfwO1KaLP8WS2QMGtWz7phfJOU4rH-uhW5X8Wov-xEU=@proton.me> Message-ID: On Wed, 31 May 2023 at 12:03, James Schaffler via Python-list wrote: > > On Tuesday, May 30th, 2023 at 9:14 PM, Greg Ewing wrote: > > Globals you create by executing code in the REPL have their own > > namespace. But everything else is shared -- builtins, imported > > Python modules, imported C extension modules, etc. etc. > > Thanks for the explanation. Could you elaborate on precisely how "everything else is shared"? As far as I understand, if you run the following code: > > from code import InteractiveInterpreter > interp = InteractiveInterpreter() > import numpy as np > interp.runcode("np.__name__") > > this will result in the error > Traceback (most recent call last): > File "", line 1, in > NameError: name 'np' is not defined > > which seems to imply that imports in the parent shell are not shared with interpreters and vice versa (if you swap the places of the import and the __name__ call). > Yep, what you're seeing there is the namespace and nothing else. But if you mess with an actual builtin object, it'll be changed for the other interpreter too. >>> import ctypes >>> ctypes.cast(id(42), ctypes.POINTER(ctypes.c_int))[6] = 43 >>> 41+1 43 >>> from code import InteractiveInterpreter >>> interp = InteractiveInterpreter() >>> interp.runcode("print(41+1)") 43 (Note that this only works in CPython and only with integers small enough to be in the cache, meaning that there is only one such object representing that integer.) The same is true of C extensions, which often have their own internal state, and that state isn't isolated to a single interpreter. Better isolation is coming with PEP 554 https://peps.python.org/pep-0554/ which also has some great information about what currently is NOT isolated. (Also, even then, some things won't be fully isolated; I think that the ctypes trick above might still affect a subinterpreter even in a post-PEP554 world.) ChrisA From ahsanmalik.ly at gmail.com Wed May 31 03:22:11 2023 From: ahsanmalik.ly at gmail.com (ahsan iqbal) Date: Wed, 31 May 2023 00:22:11 -0700 (PDT) Subject: Log File Message-ID: <2bd219c2-3a68-4fcc-9ffe-95f2eb83ecfan@googlegroups.com> Why we need a log file ? If i read a large text file than how log file help me in this regard? From toby+esnews at tobiah.org Wed May 31 09:31:20 2023 From: toby+esnews at tobiah.org (Tobiah) Date: Wed, 31 May 2023 06:31:20 -0700 Subject: Log File In-Reply-To: <2bd219c2-3a68-4fcc-9ffe-95f2eb83ecfan@googlegroups.com> References: <2bd219c2-3a68-4fcc-9ffe-95f2eb83ecfan@googlegroups.com> Message-ID: On 5/31/23 00:22, ahsan iqbal wrote: > Why we need a log file ? If i read a large text file than how log file help me in this regard? If you were parsing each line of this text file looking for information, perhaps some of the lines would not be formatted correctly, and you would be unable to get the information from those lines. Maybe you would like to write those bad lines to a log file so that you could analyze them later. From v.rakesh4uin at gmail.com Wed May 31 01:03:50 2023 From: v.rakesh4uin at gmail.com (Rakesh Vettrivel) Date: Wed, 31 May 2023 10:33:50 +0530 Subject: Regarding- Issue on package install Message-ID: I have an issue on updating both pip and setup tools, setuptools latest version is getting installed successfully but after giving ok still its shows to update. pip is not getting installed and it shows some error. Help me please with these issue. pip error: Collecting pip==23.1.2 Using cached pip-23.1.2-py3-none-any.whl (2.1 MB) Installing collected packages: pip Attempting uninstall: pip Found existing installation: pip 23.0 Uninstalling pip-23.0: Successfully uninstalled pip-23.0 Rolling back uninstall of pip Moving to c:\users\rajesh.k\appdata\roaming\python\python38\scripts\ from C:\Users\RAJESH.K\AppData\Roaming\Python\Python38\~cripts Moving to c:\users\rajesh.k\appdata\roaming\python\python38\site-packages\pip-23.0.dist-info\ from C:\Users\RAJESH.K\AppData\Roaming\Python\Python38\site-packages\~ip-23.0.dist-info Moving to c:\users\rajesh.k\appdata\roaming\python\python38\site-packages\pip\ from C:\Users\RAJESH.K\AppData\Roaming\Python\Python38\site-packages\~ip ERROR: Exception: Traceback (most recent call last): File "C:\Users\RAJESH.K\AppData\Roaming\Python\Python38\site-packages\pip\_internal\cli\base_command.py", line 160, in exc_logging_wrapper status = run_func(*args) File "C:\Users\RAJESH.K\AppData\Roaming\Python\Python38\site-packages\pip\_internal\cli\req_command.py", line 247, in wrapper return func(self, options, args) File "C:\Users\RAJESH.K\AppData\Roaming\Python\Python38\site-packages\pip\_internal\commands\install.py", line 503, in run installed = install_given_reqs( File "C:\Users\RAJESH.K\AppData\Roaming\Python\Python38\site-packages\pip\_internal\req\__init__.py", line 73, in install_given_reqs requirement.install( File "C:\Users\RAJESH.K\AppData\Roaming\Python\Python38\site-packages\pip\_internal\req\req_install.py", line 796, in install install_wheel( File "C:\Users\RAJESH.K\AppData\Roaming\Python\Python38\site-packages\pip\_internal\operations\install\wheel.py", line 729, in install_wheel _install_wheel( File "C:\Users\RAJESH.K\AppData\Roaming\Python\Python38\site-packages\pip\_internal\operations\install\wheel.py", line 646, in _install_wheel generated_console_scripts = maker.make_multiple(scripts_to_generate) File "C:\Users\RAJESH.K\AppData\Roaming\Python\Python38\site-packages\pip\_vendor\distlib\scripts.py", line 436, in make_multiple filenames.extend(self.make(specification, options)) File "C:\Users\RAJESH.K\AppData\Roaming\Python\Python38\site-packages\pip\_internal\operations\install\wheel.py", line 427, in make return super().make(specification, options) File "C:\Users\RAJESH.K\AppData\Roaming\Python\Python38\site-packages\pip\_vendor\distlib\scripts.py", line 425, in make self._make_script(entry, filenames, options=options) File "C:\Users\RAJESH.K\AppData\Roaming\Python\Python38\site-packages\pip\_vendor\distlib\scripts.py", line 325, in _make_script self._write_script(scriptnames, shebang, script, filenames, ext) File "C:\Users\RAJESH.K\AppData\Roaming\Python\Python38\site-packages\pip\_vendor\distlib\scripts.py", line 249, in _write_script launcher = self._get_launcher('t') File "C:\Users\RAJESH.K\AppData\Roaming\Python\Python38\site-packages\pip\_vendor\distlib\scripts.py", line 404, in _get_launcher raise ValueError(msg) ValueError: Unable to find resource t32.exe in package pip._vendor.distlib [notice] A new release of pip is available: 23.0 -> 23.1.2 [notice] To update, run: python.exe -m pip install --upgrade pip i tried this too but it didn't work. From vpaijc at gmail.com Wed May 31 01:12:42 2023 From: vpaijc at gmail.com (Vishal Chandratreya) Date: Wed, 31 May 2023 10:42:42 +0530 Subject: Resolution of paths in tracebacks Message-ID: When an exception occurs, the full path to the file from which it originates is displayed, but redundant elements are not removed. For instance: $ ./python ./foo Traceback (most recent call last): File "/home/User/cpython/./foo", line 4, in a() File "/home/User/cpython/./foo", line 3, in a def a(): raise ValueError ValueError This happens because the function _Py_abspath (in Python/fileutils.c) appends relative_path_to_file to absolute_path_to_current_working_directory. Not sure if this should be treated as a bug, because the definition of 'absolute path' is not clear. Does it mean a path starting from the root directory, or a path without redundant elements? The os module, for instance, does the following. $ ./python >>> import os.path >>> os.path.isabs('/home/..') True >>> os.path.abspath('/home/..') '/' Either way: should the traceback display the path without redundant elements? I am using CPython 3.13.0a0 (595ffddb33e95d8fa11999ddb873d08e3565d2eb). From markbass649 at gmail.com Wed May 31 03:34:48 2023 From: markbass649 at gmail.com (Mark Bass) Date: Wed, 31 May 2023 08:34:48 +0100 Subject: Fwd: Problems Installing and getting started. In-Reply-To: References: Message-ID: ---------- Forwarded message --------- From: Mark Bass Date: Wed, 31 May 2023 at 08:09 Subject: Problems Installing and getting started. To: Good morning, I installed python several hours ago (from python.org), I then installed the IDE PyCharm. I'm using AI to help with a project that requires statistical analysis. I cannot open python, when I double clicked a "Modify Setup" window appeared with the three options Modify, Repair and Uninstall to click. I assumed this was part of the final installation process and clicked Modify - it seemed to be successful. I still could not open python. I asked the AI and it suggested to click Repair, this still made no difference. I finally Uninstalled it, shut down my laptop, had a coffee then re-installed it but the same problem occurred. Can you help ? Any suggestions? I'm really pleased with the AI so far and looking forward to using Python to get my project started. Best Regards.....Mark From Richard at damon-family.org Wed May 31 12:09:39 2023 From: Richard at damon-family.org (Richard Damon) Date: Wed, 31 May 2023 12:09:39 -0400 Subject: Problems Installing and getting started. In-Reply-To: References: Message-ID: <3B5CFEAA-89A1-45FD-8B04-7CCBB71625FF@damon-family.org> How are you trying to ?Open? python? If you get that option screen, that sounds like you are trying to run the installer again. Knowing your Operating System would be very helpful. Python is normally run from the command line, or since you have the PyCharm IDE, it can run python on the program you have loaded into the project. > On May 31, 2023, at 11:55 AM, Mark Bass wrote: > > ?---------- Forwarded message --------- > From: Mark Bass > Date: Wed, 31 May 2023 at 08:09 > Subject: Problems Installing and getting started. > To: > > > Good morning, > > I installed python several hours ago (from python.org), I then installed > the IDE PyCharm. I'm using AI to help with a project that requires > statistical analysis. > I cannot open python, when I double clicked a "Modify Setup" window > appeared with the three options Modify, Repair and Uninstall to click. I > assumed this was part of the final installation process and clicked Modify > - it seemed to be successful. I still could not open python. I asked the AI > and it suggested to click Repair, this still made no difference. I finally > Uninstalled it, shut down my laptop, had a coffee then re-installed it but > the same problem occurred. > Can you help ? Any suggestions? > I'm really pleased with the AI so far and looking forward to using Python > to get my project started. > Best Regards.....Mark > -- > https://mail.python.org/mailman/listinfo/python-list From grant.b.edwards at gmail.com Wed May 31 12:25:11 2023 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Wed, 31 May 2023 09:25:11 -0700 (PDT) Subject: Resolution of paths in tracebacks References: Message-ID: <647774e7.920a0220.2f7e6.484f@mx.google.com> On 2023-05-31, Vishal Chandratreya wrote: > When an exception occurs, the full path to the file from which it > originates is displayed, but redundant elements are not removed. For > instance: > $ ./python ./foo > Traceback (most recent call last): > File "/home/User/cpython/./foo", line 4, in > a() > File "/home/User/cpython/./foo", line 3, in a > def a(): raise ValueError > ValueError > This happens because the function _Py_abspath (in Python/fileutils.c) > appends relative_path_to_file to absolute_path_to_current_working_directory. > Not sure if this should be treated as a bug, because the definition of > 'absolute path' is not clear. Does it mean a path starting from the root > directory, or a path without redundant elements? The former: https://www.linuxfoundation.org/blog/blog/classic-sysadmin-absolute-path-vs-relative-path-in-linux-unix From python at mrabarnett.plus.com Wed May 31 12:29:32 2023 From: python at mrabarnett.plus.com (MRAB) Date: Wed, 31 May 2023 17:29:32 +0100 Subject: Fwd: Problems Installing and getting started. In-Reply-To: References: Message-ID: <94496e63-3198-14bd-dbc8-72d20778913e@mrabarnett.plus.com> On 2023-05-31 08:34, Mark Bass wrote: > ---------- Forwarded message --------- > From: Mark Bass > Date: Wed, 31 May 2023 at 08:09 > Subject: Problems Installing and getting started. > To: > > > Good morning, > > I installed python several hours ago (from python.org), I then installed > the IDE PyCharm. I'm using AI to help with a project that requires > statistical analysis. > I cannot open python, when I double clicked a "Modify Setup" window > appeared with the three options Modify, Repair and Uninstall to click. I > assumed this was part of the final installation process and clicked Modify > - it seemed to be successful. I still could not open python. I asked the AI > and it suggested to click Repair, this still made no difference. I finally > Uninstalled it, shut down my laptop, had a coffee then re-installed it but > the same problem occurred. > Can you help ? Any suggestions? > I'm really pleased with the AI so far and looking forward to using Python > to get my project started. > What do you mean by "open python"? You said that a "Modify Setup" window appeared, which sounds like you're clicking on the *installer*. To make it clear, the file that you download from python.org is the installer. It installs Python only. It's not an IDE. Having said that, the standard distribution from python.org does come with IDLE. You should be running PyCharm that you installed; that's the IDE. You just need to ensure that it's using the version of Python that you've installed. From jsf80238 at gmail.com Wed May 31 14:10:48 2023 From: jsf80238 at gmail.com (Jason Friedman) Date: Wed, 31 May 2023 12:10:48 -0600 Subject: Best practice for database connection Message-ID: I'm trying to reconcile two best practices which seem to conflict. 1) Use a _with_ clause when connecting to a database so the connection is closed in case of premature exit. class_name = 'oracle.jdbc.OracleDriver' url = f"jdbc:oracle:thin:@//{host_name}:{port_number}/{database_name}" with jdbc.connect(class_name, url, [user_name, password], jdbc_jar_file.as_posix()) as connection: logger.info(f"Connected.") 2) Use self-made functions to streamline code. For example, there are several places I need to know if the database object is a particular type, so I create a function like this: foobar_set = set() ... def is_foobar(connection: jdbc.Connection, name: str) -> bool: """ :param connection: connection object :param name: owner.object :return: True if this object is of type foobar """ global foobar_set if not foobar_set: query = f"""select stuff from stuff""" cursor = connection.cursor() cursor.execute(query) for owner, object_name in cursor.fetchall(): foobar_set.add(f"{owner}.{object_name}") cursor.close() return name.upper() in foobar_set But that requires that I call is_foobar() with a connection object. Essentially I'd like a function that leverages the one connection I create at the beginning using a with clause. From list1 at tompassin.net Wed May 31 14:45:16 2023 From: list1 at tompassin.net (Thomas Passin) Date: Wed, 31 May 2023 14:45:16 -0400 Subject: Best practice for database connection In-Reply-To: References: Message-ID: <3cbabd14-f6c7-46b1-dbcc-6a8200e725f0@tompassin.net> On 5/31/2023 2:10 PM, Jason Friedman wrote: > I'm trying to reconcile two best practices which seem to conflict. > > 1) Use a _with_ clause when connecting to a database so the connection is > closed in case of premature exit. > > class_name = 'oracle.jdbc.OracleDriver' > url = f"jdbc:oracle:thin:@//{host_name}:{port_number}/{database_name}" > with jdbc.connect(class_name, url, [user_name, password], > jdbc_jar_file.as_posix()) as connection: > logger.info(f"Connected.") > > 2) Use self-made functions to streamline code. For example, there are > several places I need to know if the database object is a particular type, > so I create a function like this: > > foobar_set = set() > ... > def is_foobar(connection: jdbc.Connection, name: str) -> bool: > """ > :param connection: connection object > :param name: owner.object > :return: True if this object is of type foobar > """ > global foobar_set > if not foobar_set: > query = f"""select stuff from stuff""" > cursor = connection.cursor() > cursor.execute(query) > for owner, object_name in cursor.fetchall(): > foobar_set.add(f"{owner}.{object_name}") > cursor.close() > return name.upper() in foobar_set > > > But that requires that I call is_foobar() with a connection object. > > Essentially I'd like a function that leverages the one connection I create > at the beginning using a with clause. If you need to have a connection object that persists outside of the with block, then 1. you can just not use a "with" block: connection = jdbc.connect(class_name, url, [user_name, password], jdbc_jar_file.as_posix()) You will want to close the connection yourself when you are done with it. 2. do all the subsequent work within the "with" block. From wlfraed at ix.netcom.com Wed May 31 15:52:50 2023 From: wlfraed at ix.netcom.com (Dennis Lee Bieber) Date: Wed, 31 May 2023 15:52:50 -0400 Subject: Fwd: Problems Installing and getting started. References: Message-ID: On Wed, 31 May 2023 08:34:48 +0100, Mark Bass declaimed the following: >---------- Forwarded message --------- >From: Mark Bass >Date: Wed, 31 May 2023 at 08:09 >Subject: Problems Installing and getting started. >To: > > >Good morning, > >I installed python several hours ago (from python.org), I then installed >the IDE PyCharm. I'm using AI to help with a project that requires >statistical analysis. >I cannot open python, when I double clicked a "Modify Setup" window >appeared with the three options Modify, Repair and Uninstall to click. I >assumed this was part of the final installation process and clicked Modify >- it seemed to be successful. I still could not open python. I asked the AI >and it suggested to click Repair, this still made no difference. I finally >Uninstalled it, shut down my laptop, had a coffee then re-installed it but >the same problem occurred. >Can you help ? Any suggestions? >I'm really pleased with the AI so far and looking forward to using Python >to get my project started. >Best Regards.....Mark You are RERUNNING the Python installer package. Once you installed Python -- move that installer package to some safe/obscure location on your computer (you should only need it if you really need to fix an error with the installation). Python does not provide, normally, a "click me" icon to run Python. Python is a command line language INTERPRETER/COMPILER. If file associations are set up, clicking on a script (.py) file /will/ run it -- but the window it opens goes away as soon as the script completes. Instead one opens a command shell window and runs Python/scripts from that window... Microsoft Windows [Version 10.0.19045.2965] (c) Microsoft Corporation. All rights reserved. C:\Users\Owner>python Python 3.10.11 (tags/v3.10.11:7d4cc5a, Apr 5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> C:\Users\Owner>dir *.py Volume in drive C is Sys_OS Volume Serial Number is B650-6F92 Directory of C:\Users\Owner 04/15/2023 04:57 PM 50 junk.py 1 File(s) 50 bytes 0 Dir(s) 1,884,894,617,600 bytes free C:\Users\Owner>python junk.py 2 4 6 8 10 12 C:\Users\Owner>junk.py 2 4 6 8 10 12 C:\Users\Owner> Note: depending upon your environment, neither file associates nor Python may be set up on the path. You may have a "py" command that is set up to find and run Python (and allow specifying which version if you have multiple versions (in different directories). Also, you may be affected by whether Python was installed for "all users" or just the account that did the install. From list1 at tompassin.net Wed May 31 16:33:01 2023 From: list1 at tompassin.net (Thomas Passin) Date: Wed, 31 May 2023 16:33:01 -0400 Subject: Fwd: Problems Installing and getting started. In-Reply-To: References: Message-ID: <3cc99b63-c293-0749-92f8-84d52879179d@tompassin.net> On 5/31/2023 3:52 PM, Dennis Lee Bieber wrote: > Python does not provide, normally, a "click me" icon to run Python. > Python is a command line language INTERPRETER/COMPILER. If file > associations are set up, clicking on a script (.py) file/will/ run it -- > but the window it opens goes away as soon as the script completes. Instead > one opens a command shell window and runs Python/scripts from that > window... > > Microsoft Windows [Version 10.0.19045.2965] > (c) Microsoft Corporation. All rights reserved. > > C:\Users\Owner>python > Python 3.10.11 (tags/v3.10.11:7d4cc5a, Apr 5 2023, 00:38:17) [MSC v.1929 > 64 bit (AMD64)] on win32 > Type "help", "copyright", "credits" or "license" for more information. On Windows, typing "python" may or may not give the expected version depending in what has been installed before. With the python.org installation, it's better to type "py" instead (this is Windows only). For example, on my Windows 10 computer" python Python 3.9.9 (tags/v3.9.9:ccb0e6a, Nov 15 2021, 18:08:50) [MSC v.1929 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> but - py Python 3.11.3 (tags/v3.11.3:f3909b8, Apr 4 2023, 23:49:59) [MSC v.1934 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> From hjp-python at hjp.at Wed May 31 18:52:14 2023 From: hjp-python at hjp.at (Peter J. Holzer) Date: Thu, 1 Jun 2023 00:52:14 +0200 Subject: Log File In-Reply-To: <2bd219c2-3a68-4fcc-9ffe-95f2eb83ecfan@googlegroups.com> References: <2bd219c2-3a68-4fcc-9ffe-95f2eb83ecfan@googlegroups.com> Message-ID: <20230531225214.zwz2qx5m2qfpcvdj@hjp.at> On 2023-05-31 00:22:11 -0700, ahsan iqbal wrote: > Why we need a log file ? A log file contains information about what your program was doing. You use it to check that your program was performing as intended after the fact. This is especially useful for tracking down problems with programs which are either long-running or are running unattended. For example, if a user tells me that they were having a problem yesterday evening I can read the log file to see what my program was doing at the time which will help me to pin down the problem. The important part to remember is that a log file will only contain information the program writes. If you didn't think to log some information then it won't be in the log file and you can't look it up afterwards. On the other hand you don't want to log too much information because that might cause performance problems, it might fill up your disks and it will be a chore to find the relevant information in a sea of irrelevant details. So deciding what to log is a bit of an art. > If i read a large text file than how log file help me in this regard? It won't help you with reading the file. However, you might want to log some information about operation, e.g. when you started (log files usually contain time stamps), when you ended, how large the file was, etc. That way you can compare different runs (has the file increased in size over the last month? Was reading especially slow yesterday?). You could also log a status message every once in a while (e.g. every 100 MB or every 100000 lines). That will give you reassurance that the program is working and a rough estimate when it will be finished. Or you can log any other information you think might be useful. 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 PythonList at DancesWithMice.info Wed May 31 22:11:47 2023 From: PythonList at DancesWithMice.info (dn) Date: Thu, 1 Jun 2023 14:11:47 +1200 Subject: Best practice for database connection In-Reply-To: <3cbabd14-f6c7-46b1-dbcc-6a8200e725f0@tompassin.net> References: <3cbabd14-f6c7-46b1-dbcc-6a8200e725f0@tompassin.net> Message-ID: On 01/06/2023 06.45, Thomas Passin wrote: > On 5/31/2023 2:10 PM, Jason Friedman wrote: >> I'm trying to reconcile two best practices which seem to conflict. >> >> 1) Use a _with_ clause when connecting to a database so the connection is >> closed in case of premature exit. >> >> class_name = 'oracle.jdbc.OracleDriver' >> url = f"jdbc:oracle:thin:@//{host_name}:{port_number}/{database_name}" >> with jdbc.connect(class_name, url, [user_name, password], >> jdbc_jar_file.as_posix()) as connection: >> ???? logger.info(f"Connected.") >> >> 2) Use self-made functions to streamline code. For example, there are >> several places I need to know if the database object is a particular >> type, >> so I create a function like this: >> >> foobar_set = set() >> ... >> def is_foobar(connection: jdbc.Connection, name: str) -> bool: >> ???? """ >> ???? :param connection: connection object >> ???? :param name: owner.object >> ???? :return: True if this object is of type foobar >> ???? """ >> ???? global foobar_set >> ???? if not foobar_set: >> ???????? query = f"""select stuff from stuff""" >> ???????? cursor = connection.cursor() >> ???????? cursor.execute(query) >> ???????? for owner, object_name in cursor.fetchall(): >> ???????????? foobar_set.add(f"{owner}.{object_name}") >> ???????? cursor.close() >> ???? return name.upper() in foobar_set >> >> >> But that requires that I call is_foobar() with a connection object. >> >> Essentially I'd like a function that leverages the one connection I >> create >> at the beginning using a with clause. > > If you need to have a connection object that persists outside of the > with block, then > > 1. you can just not use a "with" block: > > connection = jdbc.connect(class_name, url, [user_name, password], > ?? jdbc_jar_file.as_posix()) > > You will want to close the connection yourself when you are done with it. > > 2. do all the subsequent work within the "with" block. As with many such questions, the answer is "it depends". Sadly that's no help! Please consider: is the database critical to this application? In other words, if the script is unable to proceed without access, eg RDBMS is down or credentials are not accepted, then must the logic simply stop? Most of mine fit into that category. Accordingly, script-execution starts with setting the environment, eg gathering credentials; followed by establishing a connection to the RDBMS. An operational RDBMS is part of the environment! Now (wait for many of our colleagues to hurriedly suck in their breath) we can see that the connection is a global-value - something which resides in a base "frame" of the Python stack, and is accordingly available (R-O) 'everywhere'. NB when I say "connection", it is part of a wider RDBMS-interface object. If you wish to use a Context Manager, then its only content may be a call to main() - or preferably a function which better describes what the application will do. (per @Thomas' contribution) PS I don't like using the global keyword/command, but prefer to pass the connection as a parameter. A matter of style? A "contract": no-connection, no-query? YMMV... Another approach might be to enact the Dependency Inversion Principle (one of 'Uncle Bob' Martin's SOLID Principles. In this case, proceed with the application, and when it comes time to issue a query against the database, ask the question: "does a connection exist?". In the negative case, then call a routine which establishes the connector, passes that to the query-routine, and proceeds. Assuming multiple query-routines, the problem with this is that it takes some sleight-of-hand to create a shared connection. Alternately, maybe the application is prepared to assume the 'cost' of creating multiple connections (over time) because the RDBMS-interactions are few-and-far between, or only a small part of the total. I don't use one, but others enthuse about ORMs, eg SQLAlchemy. This suits those who combine RDBMS and OOP, and has its own persistence methodology. -- Regards, =dn From jschaffler at proton.me Wed May 31 22:08:56 2023 From: jschaffler at proton.me (James Schaffler) Date: Thu, 01 Jun 2023 02:08:56 +0000 Subject: Why does IDLE use a subprocess? In-Reply-To: References: <0yjTTMo6f2sNAeHM8DWbLsJ3Yh3N1Fc-9MUmGXN4PoQ7rh3ovCCCEDrEb-UkCDWxIfwO1KaLP8WS2QMGtWz7phfJOU4rH-uhW5X8Wov-xEU=@proton.me> Message-ID: On Tuesday, May 30th, 2023 at 10:18 PM, Chris Angelico wrote: > Yep, what you're seeing there is the namespace and nothing else. But > if you mess with an actual builtin object, it'll be changed for the > other interpreter too. > > > > > import ctypes > > > > ctypes.cast(id(42), ctypes.POINTER(ctypes.c_int))[6] = 43 > > > > 41+1 > > 43 > > > > > from code import InteractiveInterpreter > > > > interp = InteractiveInterpreter() > > > > interp.runcode("print(41+1)") > > 43 > > (Note that this only works in CPython and only with integers small > enough to be in the cache, meaning that there is only one such object > representing that integer.) > > The same is true of C extensions, which often have their own internal > state, and that state isn't isolated to a single interpreter. > > Better isolation is coming with PEP 554 > https://peps.python.org/pep-0554/ which also has some great > information about what currently is NOT isolated. (Also, even then, > some things won't be fully isolated; I think that the ctypes trick > above might still affect a subinterpreter even in a post-PEP554 > world.) Amazing example! Thank you everyone for the detailed responses - will be sure to check out the PEP as well. Jim