From learn2program at gmail.com Fri Sep 1 03:57:22 2023 From: learn2program at gmail.com (Alan Gauld) Date: Fri, 1 Sep 2023 08:57:22 +0100 Subject: Why do I always get an exception raised in this __init__()? In-Reply-To: References: Message-ID: On 31/08/2023 22:15, Chris Green via Python-list wrote: > class Gpiopin: > > def __init__(self, pin): > # > # > # scan through the GPIO chips to find the line/pin we want > # > for c in ['gpiochip0', 'gpiochip1', 'gpiochip2', 'gpiochip3']: > > chip = gpiod.Chip(c) > for l in range(32): > line = chip.get_line(l) > if pin in line.name(): > print("Found: ", line.name()) > return > else: > raise ValueError("Can't find pin '" + pin + "'") You don't store the line anywhere. You need to use self.line self.line = chip.get_line(l) if pin... > def print_name(self): > print (self.line.name()) > > def set(self): > self.line.set_value(1) > > def clear(self): > self.line.set_value(0) As you do here. -- 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 lists at mostrom.pp.se Sun Sep 3 12:10:29 2023 From: lists at mostrom.pp.se (=?utf-8?q?Jan_Erik_Mostr=C3=B6m?=) Date: Sun, 03 Sep 2023 18:10:29 +0200 Subject: Passing info to function used in re.sub Message-ID: <6943DF5C-BBD7-40FB-872E-87F111D52059@mostrom.pp.se> I'm looking for some advice for how to write this in a clean way I want to replace some text using a regex-pattern, but before creating replacement text I need to some file checking/copying etc. My code right now look something like this: def fix_stuff(m): # Do various things that involves for info # that what's available in m replacement_text = m.group(1) + global_var1 + global_var2 return replacement_text and the call comes here global_var1 = "bla bla" global_var2 = "pff" new_text = re.sub(im_pattern,fix_stuff,md_text) The "problem" is that I've currently written some code that works but it uses global variables ... and I don't like global variables. I assume there is a better way to write this, but how? = jem From python at mrabarnett.plus.com Sun Sep 3 13:13:10 2023 From: python at mrabarnett.plus.com (MRAB) Date: Sun, 3 Sep 2023 18:13:10 +0100 Subject: Passing info to function used in re.sub In-Reply-To: <6943DF5C-BBD7-40FB-872E-87F111D52059@mostrom.pp.se> References: <6943DF5C-BBD7-40FB-872E-87F111D52059@mostrom.pp.se> Message-ID: On 2023-09-03 17:10, Jan Erik Mostr?m via Python-list wrote: > I'm looking for some advice for how to write this in a clean way > > I want to replace some text using a regex-pattern, but before creating replacement text I need to some file checking/copying etc. My code right now look something like this: > > def fix_stuff(m): > # Do various things that involves for info > # that what's available in m > replacement_text = m.group(1) + global_var1 + global_var2 > return replacement_text > > and the call comes here > > global_var1 = "bla bla" > global_var2 = "pff" > > new_text = re.sub(im_pattern,fix_stuff,md_text) > > > The "problem" is that I've currently written some code that works but it uses global variables ... and I don't like global variables. I assume there is a better way to write this, but how? > You could use pass an anonymous function (a lambda) to re.sub: def fix_stuff(m, var1, var2): # Do various things that involves for info # that what's available in m replacement_text = m.group(1) + var1 + var2 return replacement_text global_var1 = "bla bla" global_var2 = "pff" new_text = re.sub(im_pattern, lambda m, var1=global_var1, var2=global_var2: fix_stuff(m, var1, var2), md_text) Or, if you prefer a named function, define one just before the re.sub: def fix_stuff(m, var1, var2): # Do various things that involves for info # that what's available in m replacement_text = m.group(1) + var1 + var2 return replacement_text global_var1 = "bla bla" global_var2 = "pff" def fix_it(m, var1=global_var1, var2=global_var2): return fix_stuff(m, var1, var2) new_text = re.sub(im_pattern, fix_it, md_text) From lists at mostrom.pp.se Sun Sep 3 13:58:17 2023 From: lists at mostrom.pp.se (=?utf-8?q?Jan_Erik_Mostr=C3=B6m?=) Date: Sun, 03 Sep 2023 19:58:17 +0200 Subject: Passing info to function used in re.sub In-Reply-To: References: <6943DF5C-BBD7-40FB-872E-87F111D52059@mostrom.pp.se> Message-ID: <9FEA78CE-D274-453C-A49E-592797F336D8@mostrom.pp.se> On 3 Sep 2023, at 19:13, MRAB via Python-list wrote: > You could use pass an anonymous function (a lambda) to re.sub: Of course !! Thanks. = jem From jgossage at gmail.com Sun Sep 3 16:43:34 2023 From: jgossage at gmail.com (Jonathan Gossage) Date: Sun, 3 Sep 2023 16:43:34 -0400 Subject: Forward References Message-ID: I am attempting to use forward references in my program and I am failing. This also does not work with the older way of putting the name of a class as a string. Here is some sample code: from __future__ import annotations from dataclasses import dataclass from typing import TypeAlias ColorDef: TypeAlias = RGB | int | str @dataclass(frozen=True, slots=True) class RGB(object): Can anyone suggest how I should fix this without reversing the statement order? pass -- Jonathan Gossage From cl at isbd.net Fri Sep 1 05:04:37 2023 From: cl at isbd.net (Chris Green) Date: Fri, 1 Sep 2023 10:04:37 +0100 Subject: Why do I always get an exception raised in this __init__()? References: Message-ID: <52m8sj-ku7p.ln1@esprimo.zbmc.eu> Alan Gauld wrote: > On 31/08/2023 22:15, Chris Green via Python-list wrote: > > > class Gpiopin: > > > > def __init__(self, pin): > > # > > # > > # scan through the GPIO chips to find the line/pin we want > > # > > for c in ['gpiochip0', 'gpiochip1', 'gpiochip2', 'gpiochip3']: > > > > chip = gpiod.Chip(c) > > for l in range(32): > > line = chip.get_line(l) > > if pin in line.name(): > > print("Found: ", line.name()) > > return > > else: > > raise ValueError("Can't find pin '" + pin + "'") > > You don't store the line anywhere. > You need to use self.line > self.line = chip.get_line(l) > if pin... > > > def print_name(self): > > print (self.line.name()) > > > > def set(self): > > self.line.set_value(1) > > > > def clear(self): > > self.line.set_value(0) > > As you do here. > Yes, OK, absolutely. However that wasn't my original rather basic problem which was, as I said, that I wasn't running the code I was looking at. The above was just a quick hack from some even cruder code doing the same job, trying to develop it into something better and more general. It's all on a headless Beaglebone Black (bit like a Raspberry Pi) so I'm doing everything via multiple ssh connections and sometimes this results in "the left hand not knowing what the right hand is doing"! -- Chris Green ? From pf at pfortin.com Fri Sep 1 12:15:45 2023 From: pf at pfortin.com (Pierre Fortin) Date: Fri, 1 Sep 2023 12:15:45 -0400 Subject: iterations destroy reversed() results Message-ID: <20230901121545.0746aa1f@pfortin.com> Hi, reversed() results are fine until iterated over, after which the results are no longer available. This was discovered after using something like this: rev = reversed( sorted( list ) ) sr = sum( 1 for _ in rev ) # rev is now destroyed So reversed() results can only be iterated once unlike sorted(), etc... Script to illustrate the issue: /tmp/rev: orig = [ 'x', 'a', 'y', 'b', 'z', 'c' ] co = sum( 1 for _ in orig ) print( 'orig', orig, co ) # reversing rev = reversed(orig) print( 'before iteration:', [ x for x in rev ] ) # list comprehension was an iteration over 'rev' print( 'after iteration:', [ x for x in rev ] ) # how this was discovered... orig = [ 'x', 'a', 'y', 'b', 'z', 'c' ] rev = reversed(orig) cr = sum( 1 for _ in rev ) print( 'after sum():', [ x for x in rev ] ) which produces: $ python /tmp/rev orig ['x', 'a', 'y', 'b', 'z', 'c'] 6 before iteration: ['c', 'z', 'b', 'y', 'a', 'x'] after iteration: [] after sum(): [] Regards, Pierre From cl at isbd.net Fri Sep 1 16:48:59 2023 From: cl at isbd.net (Chris Green) Date: Fri, 1 Sep 2023 21:48:59 +0100 Subject: Finding good documentation for gpiod Message-ID: I am using the gpiod package for manipulating GPIO inputs/outputs on a Beaglebone Black SBC (like a Raspberry Pi but with more flexible I/O). Mostly I am managing to get things to work as I want but better documentation of gpiod would be a great help. For example, when one has found an I/O pin (a 'line' in GPIO parlance) that one wants to use one has to 'request' it using the Line.request() method. The help for this is as follows:- Help on method_descriptor: request(...) request(consumer[, type[, flags[, default_val]]]) -> None Request this GPIO line. consumer Name of the consumer. type Type of the request. flags Other configuration flags. default_val Default value of this line. Note: default_vals argument (sequence of default values passed down to LineBulk.request()) is still supported for backward compatibility but is now deprecated when requesting single lines. Which is pretty good **except** that I can't find a proper description of the parameters anywhere, i.e. there's nowhere that even tells me what types of values/objects the parameters are. At the end of the gpiod.Line section of the help there is this:- | ACTIVE_HIGH = 1 | | ACTIVE_LOW = 2 | | BIAS_AS_IS = 1 | | BIAS_DISABLE = 2 | | BIAS_PULL_DOWN = 4 | | BIAS_PULL_UP = 3 | | DIRECTION_INPUT = 1 | | DIRECTION_OUTPUT = 2 Which **might** be appropriate values for 'type' or 'flags' but there doesn't seem to be any way of knowing. Am I missing something very obvious somewhere? Is there a 'standard' way of finding out parameter information? It may well be that I'm simply banging up against the limit of what documentation is available, I have managed to get code working OK. It's just that I'd be happier if I really know what I was doing! :-) -- Chris Green ? From dom.grigonis at gmail.com Sun Sep 3 17:52:58 2023 From: dom.grigonis at gmail.com (Dom Grigonis) Date: Mon, 4 Sep 2023 00:52:58 +0300 Subject: iterations destroy reversed() results In-Reply-To: <20230901121545.0746aa1f@pfortin.com> References: <20230901121545.0746aa1f@pfortin.com> Message-ID: It is by design. `sorted` returns a list, while `reversed` returns an iterator. Iterators are exhaust-able, and not reusable. So be mindful of this and if you are going to "re-use? the sequence returned by iterator, convert it to list first. Have a look at `itertools` library, which contains a lot of such functions and many good recipes on achieving various things elegantly using iterators. > On 1 Sep 2023, at 19:15, Pierre Fortin via Python-list wrote: > > Hi, > > reversed() results are fine until iterated over, after which the > results are no longer available. This was discovered after using > something like this: > > rev = reversed( sorted( list ) ) > sr = sum( 1 for _ in rev ) > # rev is now destroyed > > So reversed() results can only be iterated once unlike sorted(), etc... > > Script to illustrate the issue: > /tmp/rev: > orig = [ 'x', 'a', 'y', 'b', 'z', 'c' ] > co = sum( 1 for _ in orig ) > print( 'orig', orig, co ) > # reversing > rev = reversed(orig) > print( 'before iteration:', [ x for x in rev ] ) > # list comprehension was an iteration over 'rev' > print( 'after iteration:', [ x for x in rev ] ) > # how this was discovered... > orig = [ 'x', 'a', 'y', 'b', 'z', 'c' ] > rev = reversed(orig) > cr = sum( 1 for _ in rev ) > print( 'after sum():', [ x for x in rev ] ) > > which produces: > > $ python /tmp/rev > orig ['x', 'a', 'y', 'b', 'z', 'c'] 6 > before iteration: ['c', 'z', 'b', 'y', 'a', 'x'] > after iteration: [] > after sum(): [] > > Regards, > Pierre > -- > https://mail.python.org/mailman/listinfo/python-list From list1 at tompassin.net Sun Sep 3 18:19:11 2023 From: list1 at tompassin.net (Thomas Passin) Date: Sun, 3 Sep 2023 18:19:11 -0400 Subject: iterations destroy reversed() results In-Reply-To: <20230901121545.0746aa1f@pfortin.com> References: <20230901121545.0746aa1f@pfortin.com> Message-ID: On 9/1/2023 12:15 PM, Pierre Fortin via Python-list wrote: > Hi, > > reversed() results are fine until iterated over, after which the > results are no longer available. This was discovered after using > something like this: > > rev = reversed( sorted( list ) ) > sr = sum( 1 for _ in rev ) > # rev is now destroyed > > So reversed() results can only be iterated once unlike sorted(), etc... reversed() is an iterator these days: >>> l1 = [1, 2, 3] >>> rev = reversed( sorted( l1 ) ) >>> type(rev) > From list1 at tompassin.net Sun Sep 3 18:20:43 2023 From: list1 at tompassin.net (Thomas Passin) Date: Sun, 3 Sep 2023 18:20:43 -0400 Subject: Passing info to function used in re.sub In-Reply-To: <6943DF5C-BBD7-40FB-872E-87F111D52059@mostrom.pp.se> References: <6943DF5C-BBD7-40FB-872E-87F111D52059@mostrom.pp.se> Message-ID: <6b112785-2d66-c566-c9be-216f034cd733@tompassin.net> On 9/3/2023 12:10 PM, Jan Erik Mostr?m via Python-list wrote: > I'm looking for some advice for how to write this in a clean way > > I want to replace some text using a regex-pattern, but before creating replacement text I need to some file checking/copying etc. My code right now look something like this: > > def fix_stuff(m): > # Do various things that involves for info > # that what's available in m > replacement_text = m.group(1) + global_var1 + global_var2 > return replacement_text > > and the call comes here > > global_var1 = "bla bla" > global_var2 = "pff" > > new_text = re.sub(im_pattern,fix_stuff,md_text) > > > The "problem" is that I've currently written some code that works but it uses global variables ... and I don't like global variables. I assume there is a better way to write this, but how? > > = jem There are two things to keep in mind here, I think. First, in Python a "global" variable is really module-level, so variables specific to one module seem fine and are common practice. Second, the way you have written this example, it looks like these module-level "variables" are in effect constants. In other words, they are just shorthand for specific declared quantities. If this is so, then it makes even more sense to define them as module-level objects in the module that needs to use them. If you still don't want to use them as "global" in your module, then define them in a separate module and import them from that module. From rosuav at gmail.com Sun Sep 3 18:42:41 2023 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 4 Sep 2023 08:42:41 +1000 Subject: iterations destroy reversed() results In-Reply-To: <20230901121545.0746aa1f@pfortin.com> References: <20230901121545.0746aa1f@pfortin.com> Message-ID: On Mon, 4 Sept 2023 at 07:44, Pierre Fortin via Python-list wrote: > > Hi, > > reversed() results are fine until iterated over, after which the > results are no longer available. This was discovered after using > something like this: > > rev = reversed( sorted( list ) ) > sr = sum( 1 for _ in rev ) > # rev is now destroyed > > So reversed() results can only be iterated once unlike sorted(), etc... reversed() is like iter(), and should be used the same way: for item in reversed(list): If you want to eagerly construct a full reversed list, instead slice the list: list[::-1] ChrisA From python at mrabarnett.plus.com Sun Sep 3 18:56:37 2023 From: python at mrabarnett.plus.com (MRAB) Date: Sun, 3 Sep 2023 23:56:37 +0100 Subject: Forward References In-Reply-To: References: Message-ID: <21022483-f694-1080-9ecc-11826514468d@mrabarnett.plus.com> On 2023-09-03 21:43, Jonathan Gossage via Python-list wrote: > I am attempting to use forward references in my program and I am failing. > This also does not work with the older way of putting the name of a class > as a string. Here is some sample code: > > from __future__ import annotations > > from dataclasses import dataclass > from typing import TypeAlias > > > ColorDef: TypeAlias = RGB | int | str > > > > @dataclass(frozen=True, slots=True) > class RGB(object): > > Can anyone suggest how I should fix this without reversing the statement > order? > > pass > The usual way to deal with forward type references is to use a string literal, i.e. 'RGB', but that doesn't work with '|', so use typing.Union instead: from typing import TypeAlias, Union ColorDef: TypeAlias = Union['RGB', int, str] From barry at barrys-emacs.org Mon Sep 4 01:22:11 2023 From: barry at barrys-emacs.org (Barry) Date: Mon, 4 Sep 2023 06:22:11 +0100 Subject: Finding good documentation for gpiod In-Reply-To: References: Message-ID: <8FDE2607-A899-4BE2-B509-B947D119D499@barrys-emacs.org> E > On 3 Sep 2023, at 22:49, Chris Green via Python-list wrote: > > Mostly I am managing to get things to work as I want but better > documentation of gpiod would be a great help. Ask the author? https://github.com/aswild/python-gpiod Maybe read the source code for hints? Barry From hjp-python at hjp.at Mon Sep 4 15:00:02 2023 From: hjp-python at hjp.at (Peter J. Holzer) Date: Mon, 4 Sep 2023 21:00:02 +0200 Subject: Passing info to function used in re.sub In-Reply-To: <6943DF5C-BBD7-40FB-872E-87F111D52059@mostrom.pp.se> References: <6943DF5C-BBD7-40FB-872E-87F111D52059@mostrom.pp.se> Message-ID: <20230904190002.2vh7mcqi6xkb6rvu@hjp.at> On 2023-09-03 18:10:29 +0200, Jan Erik Mostr?m via Python-list wrote: > I want to replace some text using a regex-pattern, but before creating > replacement text I need to some file checking/copying etc. My code > right now look something like this: > > def fix_stuff(m): > # Do various things that involves for info > # that what's available in m > replacement_text = m.group(1) + global_var1 + global_var2 > return replacement_text > > and the call comes here > > global_var1 = "bla bla" > global_var2 = "pff" > > new_text = re.sub(im_pattern,fix_stuff,md_text) > > > The "problem" is that I've currently written some code that works but > it uses global variables ... and I don't like global variables. I > assume there is a better way to write this, but how? If you use fix_stuff only inside one other function, you could make it local to that function so that it will capture the local variables of the outer function: import re def demo(): local_var1 = "bla bla" local_var2 = "pff" def fix_stuff(m): # Do various things that involves for info # that what's available in m replacement_text = m.group(1) + local_var1 + local_var2 return replacement_text for md_text in ( "aardvark", "barbapapa", "ba ba ba ba barbara ann"): new_text = re.sub(r"(a+).*?(b+)", fix_stuff, md_text) print(md_text, new_text) demo() 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 dieter at handshake.de Mon Sep 4 15:37:30 2023 From: dieter at handshake.de (Dieter Maurer) Date: Mon, 4 Sep 2023 21:37:30 +0200 Subject: Passing info to function used in re.sub In-Reply-To: <6943DF5C-BBD7-40FB-872E-87F111D52059@mostrom.pp.se> References: <6943DF5C-BBD7-40FB-872E-87F111D52059@mostrom.pp.se> Message-ID: <25846.12794.105257.170108@ixdm.fritz.box> Jan Erik Mostr?m wrote at 2023-9-3 18:10 +0200: >I'm looking for some advice for how to write this in a clean way > ... >The "problem" is that I've currently written some code that works but it uses global variables ... and I don't like global variables. I assume there is a better way to write this, but how? You could define a class with a `__call__` method and use an instance of the class as replacement. The class and/or instance can provide all relevant information via attributes. From lists at mostrom.pp.se Tue Sep 5 04:05:11 2023 From: lists at mostrom.pp.se (=?utf-8?q?Jan_Erik_Mostr=C3=B6m?=) Date: Tue, 05 Sep 2023 10:05:11 +0200 Subject: Passing info to function used in re.sub In-Reply-To: <6943DF5C-BBD7-40FB-872E-87F111D52059@mostrom.pp.se> References: <6943DF5C-BBD7-40FB-872E-87F111D52059@mostrom.pp.se> Message-ID: <1706170F-4928-4B7B-B946-39A33D12521C@mostrom.pp.se> On 3 Sep 2023, at 18:10, Jan Erik Mostr?m via Python-list wrote: > I'm looking for some advice for how to write this in a clean way Thanks for all the suggestion, I realize that I haven't written Python code in a while. I should have remembered this myself !!! Thanks for reminding me. = jem From loris.bennett at fu-berlin.de Tue Sep 5 03:32:07 2023 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Tue, 05 Sep 2023 09:32:07 +0200 Subject: Displaying CPU instruction sets used for TensorFlow build? Message-ID: <87fs3tdqiw.fsf@zedat.fu-berlin.de> Hi, Does anyone know how I can display the CPU instruction sets which were used when TensorFlow was compiled? I initially compiled TF on a machine with a CPU which supports AVX512_VNNI. I subsequently recompiled on a second machine without AVX512_VNNI, but when I run a test program on the second machine, I get the error: The TensorFlow library was compiled to use AVX512_VNNI instructions, but these aren't available on your machine. I would like to check the instruction sets explicitly, so I can tell whether I am using the version of TF I think I am, or whether the test program has some sort of problem. Cheers, Loris -- This signature is currently under constuction. From thomas at python.org Wed Sep 6 07:08:15 2023 From: thomas at python.org (Thomas Wouters) Date: Wed, 6 Sep 2023 13:08:15 +0200 Subject: Python 3.12.0 rc2 (final release candidate) now available. Message-ID: I'm pleased to announce the release of Python 3.12 release candidate 2. https://www.python.org/downloads/release/python-3120rc2/ This is the second release candidate of Python 3.12.0 This release, *3.12.0rc2*, is the last release preview for Python 3.12. There will be *no ABI changes* from this point forward in the 3.12 series. The intent is for the final release of 3.12.0, scheduled for Monday, 2023-10-02, to be identical to this release candidate. *This is the last chance to find critical problems in Python 3.12.* Call to action We strongly encourage maintainers of third-party Python projects to prepare their projects for 3.12 compatibilities during this phase, and where necessary publish Python 3.12 wheels on PyPI to be ready for the final release of 3.12.0. Any binary wheels built against Python 3.12.0rc2 will work with future versions of Python 3.12. As always, report any issues to the Python bug tracker . Please keep in mind that this is a preview release and while it?s as close to the final release as we can get it, its use is *not* recommended for production environments. Core developers: time to work on documentation now - Are all your changes properly documented? - Are they mentioned in What?s New ? - Did you notice other changes you know of to have insufficient documentation? Major new features of the 3.12 series, compared to 3.11 New features - More flexible f-string parsing , allowing many things previously disallowed (PEP 701 ). - Support for the buffer protocol in Python code (PEP 688 ). - A new debugging/profiling API (PEP 669 ). - Support for isolated subinterpreters with separate Global Interpreter Locks (PEP 684 ). - Even more improved error messages . More exceptions potentially caused by typos now make suggestions to the user. - Support for the Linux perf profiler to report Python function names in traces. - Many large and small performance improvements (like PEP 709 ), delivering an estimated 5% overall performance improvementcitation needed. Type annotations - New type annotation syntax for generic classes (PEP 695 ). - New override decorator for methods (PEP 698 ). Deprecations - 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 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 scheduled release of Python 3.12 will be 3.12.0, the *final release*, currently scheduled for 2023-10-02. More resources - Online Documentation . - PEP 693 , the Python 3.12 Release Schedule. - Report bugs via GitHub Issues . - Help fund Python and its community . We hope you enjoy the new releases! Thanks to all of the many volunteers who help make Python Development and these releases possible! Please consider supporting our efforts by volunteering yourself or through organization contributions to the Python Software Foundation . Your release team, Thomas Wouters Ned Deily Steve Dower ?ukasz Langa -- Thomas Wouters From PythonList at DancesWithMice.info Thu Sep 7 16:48:04 2023 From: PythonList at DancesWithMice.info (dn) Date: Fri, 8 Sep 2023 08:48:04 +1200 Subject: ANN: Wed 20 Sep: Terminal-based user interfaces (TUIs) with ease using Textual Message-ID: <9772f3e2-0c04-5684-fd8f-9e77067d7cd8@DancesWithMice.info> Rodrigo's back! Fresh from his successes at EuroPython... You are invited to join the next virtual NZPUG Auckland Branch meeting (Wed 20 Sep, 1830~2030 local, ie 0630~0830 UTC) Learn how to build powerful terminal-based user interfaces (TUIs) with ease using Textual - an open-source Python framework. Through this tutorial, you'll learn how to use features like Textual's built-in widgets, reactive attributes, and message-passing system, to start developing a simple TODO app that runs directly in your terminal. About Rodrigo Gir?o Serr?o: Rodrigo has presented to NZPUG Auckland Branch previously. He speaks frequently at various PyCons (Python Conferences) and other gatherings. As well as Python, he has been playing with APL, C++, and more. Combining programming and maths, he describes himself as a mathemagician. Rodrigo has always been fascinated by problem solving and that is why he picked up programming ? so that he could solve more problems. He also loves sharing knowledge, and that is why he spends so much time writing articles in his blog, writing on Twitter, and giving workshops and courses. During the week, Rodrigo can be found banging his head against the wall while trying to solve a Textual bug, as he works on Textual full-time. To RSVP (to receive the meeting-URL) and for more detail: https://www.meetup.com/nzpug-auckland/events/295433884/ The Auckland branch of the New Zealand Python Users Group meets twice monthly. You're very welcome to attend online or in-person (as available). Meeting location-details or URL will be sent to those who RSVP. We are a healthy mix of Python users. Students, academics, hobbyists, industry professionals, and many completely new to Python. The 'room' opens at 1815 (local time) with an opportunity to network with colleagues. Formal start is 1830. Aiming to finish by 2030. We are always keen to hear suggestions for meeting-topics, and to meet with folk who'd like to present or lead - eg a brief lightning talk, a practical coaching-session, a full lecture... Help is available if you've never done such a thing before! We follow the NZPUG Code of Conduct to create an inclusive and friendly environment. We express thanks to, and encourage you to investigate our sponsors: Catalyst Cloud, New Zealand Open Source Society, JetBrains, and IceHouse Ventures. -- Regards, =dn From research at johnohagan.com Mon Sep 11 08:30:21 2023 From: research at johnohagan.com (John O'Hagan) Date: Mon, 11 Sep 2023 22:30:21 +1000 Subject: Tkinter ttk Treeview binding responds to past events! Message-ID: I was surprised that the code below prints 'called' three times. from tkinter import * from tkinter.ttk import * root=Tk() def callback(*e): ? ? print('called') tree = Treeview(root) tree.pack() iid = tree.insert('', 0, text='test') tree.selection_set(iid) tree.selection_remove(iid) tree.selection_set(iid) tree.bind('<>', callback) mainloop() In other words, selection events that occurred _before_ the callback function was bound to the Treeview selections are triggering the function upon binding. AFAIK, no other tk widget/binding combination behaves this way (although I haven't tried all of them). This was a problem because I wanted to reset the contents of the Treeview without triggering a relatively expensive bound function, but found that temporarily unbinding didn't prevent the calls. I've worked around this by using a regular button-click binding for selection instead, but I'm curious if anyone can cast any light on this. Cheers John From mirkok.lists at googlemail.com Mon Sep 11 16:25:45 2023 From: mirkok.lists at googlemail.com (Mirko) Date: Mon, 11 Sep 2023 22:25:45 +0200 Subject: Tkinter ttk Treeview binding responds to past events! In-Reply-To: References: Message-ID: <084a1cfa-8889-3acd-d19c-8f204c314b7b@googlemail.com> Am 11.09.23 um 14:30 schrieb John O'Hagan via Python-list: > I was surprised that the code below prints 'called' three times. > > > from tkinter import * > from tkinter.ttk import * > > root=Tk() > > def callback(*e): > ? ? print('called') > > tree = Treeview(root) > tree.pack() > > iid = tree.insert('', 0, text='test') > > tree.selection_set(iid) > tree.selection_remove(iid) > tree.selection_set(iid) > > tree.bind('<>', callback) > > mainloop() > > In other words, selection events that occurred _before_ the callback > function was bound to the Treeview selections are triggering the > function upon binding. AFAIK, no other tk widget/binding combination > behaves this way (although I haven't tried all of them). > > This was a problem because I wanted to reset the contents of the > Treeview without triggering a relatively expensive bound function, but > found that temporarily unbinding didn't prevent the calls. > > I've worked around this by using a regular button-click binding for > selection instead, but I'm curious if anyone can cast any light on > this. > > Cheers > > John AFAIK (it's been quite some time, since I used Tk/Tkinter): These selection events are not triggered upon binding, but after the mainloop has startet. Tk's eventloop is queue-driven, so the tree.selection_{set,remove}() calls just place the events on the queue. After that, you setup a callback and when the mainloop starts, it processes the events from the queue, executing the registered callback. I seem to remember, that I solved a similar issue by deferring the callback installation using root.after(). from tkinter import * from tkinter.ttk import * root=Tk() def callback(*e): print('called') tree = Treeview(root) tree.pack() iid = tree.insert('', 0, text='test') tree.selection_set(iid) tree.selection_remove(iid) tree.selection_set(iid) root.after(100, lambda: tree.bind('<>', callback)) mainloop() This does not print "called" at all after startup (but still selects the entry), because the callback has not been installed when the mainloop starts. But any subsequent interaction with the list (clicking) will print it (since the callback is then setup). HTH From rob.cliffe at btinternet.com Mon Sep 11 17:58:59 2023 From: rob.cliffe at btinternet.com (Rob Cliffe) Date: Mon, 11 Sep 2023 22:58:59 +0100 Subject: Tkinter ttk Treeview binding responds to past events! In-Reply-To: <084a1cfa-8889-3acd-d19c-8f204c314b7b@googlemail.com> References: <084a1cfa-8889-3acd-d19c-8f204c314b7b@googlemail.com> Message-ID: On 11/09/2023 21:25, Mirko via Python-list wrote: > Am 11.09.23 um 14:30 schrieb John O'Hagan via Python-list: >> I was surprised that the code below prints 'called' three times. >> >> >> from tkinter import * >> from tkinter.ttk import * >> >> root=Tk() >> >> def callback(*e): >> ?? ? print('called') >> >> tree = Treeview(root) >> tree.pack() >> >> iid = tree.insert('', 0, text='test') >> >> tree.selection_set(iid) >> tree.selection_remove(iid) >> tree.selection_set(iid) >> >> tree.bind('<>', callback) >> >> mainloop() >> >> In other words, selection events that occurred _before_ the callback >> function was bound to the Treeview selections are triggering the >> function upon binding. AFAIK, no other tk widget/binding combination >> behaves this way (although I haven't tried all of them). >> >> This was a problem because I wanted to reset the contents of the >> Treeview without triggering a relatively expensive bound function, but >> found that temporarily unbinding didn't prevent the calls. >> >> I've worked around this by using a regular button-click binding for >> selection instead, but I'm curious if anyone can cast any light on >> this. >> >> Cheers >> >> John > > > AFAIK (it's been quite some time, since I used Tk/Tkinter): > > These selection events are not triggered upon binding, but after the > mainloop has startet. Tk's eventloop is queue-driven, so the > tree.selection_{set,remove}() calls just place the events on the > queue. After that, you setup a callback and when the mainloop starts, > it processes the events from the queue, executing the registered > callback. > > I seem to remember, that I solved a similar issue by deferring the > callback installation using root.after(). > > > from tkinter import * > from tkinter.ttk import * > > root=Tk() > > def callback(*e): > ??? print('called') > > tree = Treeview(root) > tree.pack() > > iid = tree.insert('', 0, text='test') > > tree.selection_set(iid) > tree.selection_remove(iid) > tree.selection_set(iid) > > root.after(100, lambda: tree.bind('<>', callback)) > > mainloop() > > > > This does not print "called" at all after startup (but still selects > the entry), because the callback has not been installed when the > mainloop starts. But any subsequent interaction with the list > (clicking) will print it (since the callback is then setup). > > HTH Indeed.? And you don't need to specify a delay of 100 milliseconds. 0 will work (I'm guessing that's because queued actions are performed in the order that they were queued). I have also found that after() is a cure for some ills, though I avoid using it more than I have to because it feels ... a bit fragile, perhaps. E.g. suppose the mouse is clicked on a widget and tk responds by giving that widget the focus, but I don't want that to happen. I can't AFAIK prevent the focus change, but I can immediately cancel it with ??? X.after(0, SomeOtherWidget.focus_set) where X is any convenient object with the "after" method (just about any widget, or the root). Best wishes Rob Cliffe From research at johnohagan.com Tue Sep 12 01:43:11 2023 From: research at johnohagan.com (John O'Hagan) Date: Tue, 12 Sep 2023 15:43:11 +1000 Subject: Tkinter ttk Treeview binding responds to past events! In-Reply-To: <084a1cfa-8889-3acd-d19c-8f204c314b7b@googlemail.com> References: <084a1cfa-8889-3acd-d19c-8f204c314b7b@googlemail.com> Message-ID: On Mon, 2023-09-11 at 22:25 +0200, Mirko via Python-list wrote: > Am 11.09.23 um 14:30 schrieb John O'Hagan via Python-list: > > I was surprised that the code below prints 'called' three times. > > > > > > from tkinter import * > > from tkinter.ttk import * > > > > root=Tk() > > > > def callback(*e): > > ?? ? print('called') > > > > tree = Treeview(root) > > tree.pack() > > > > iid = tree.insert('', 0, text='test') > > > > tree.selection_set(iid) > > tree.selection_remove(iid) > > tree.selection_set(iid) > > > > tree.bind('<>', callback) > > > > mainloop() > > > > In other words, selection events that occurred _before_ the > > callback > > function was bound to the Treeview selections are triggering the > > function upon binding. AFAIK, no other tk widget/binding > > combination > > behaves this way (although I haven't tried all of them). > > > > This was a problem because I wanted to reset the contents of the > > Treeview without triggering a relatively expensive bound function, > > but > > found that temporarily unbinding didn't prevent the calls. > > > > I've worked around this by using a regular button-click binding for > > selection instead, but I'm curious if anyone can cast any light on > > this. > > > > Cheers > > > > John > > > AFAIK (it's been quite some time, since I used Tk/Tkinter): > > These selection events are not triggered upon binding, but after the > mainloop has startet. Tk's eventloop is queue-driven, so the > tree.selection_{set,remove}() calls just place the events on the > queue. After that, you setup a callback and when the mainloop > starts, it processes the events from the queue, executing the > registered callback. > > I seem to remember, that I solved a similar issue by deferring the > callback installation using root.after(). > > > from tkinter import * > from tkinter.ttk import * > > root=Tk() > > def callback(*e): > ???? print('called') > > tree = Treeview(root) > tree.pack() > > iid = tree.insert('', 0, text='test') > > tree.selection_set(iid) > tree.selection_remove(iid) > tree.selection_set(iid) > > root.after(100, lambda: tree.bind('<>', callback)) > > mainloop() > > > > This does not print "called" at all after startup (but still selects > the entry), because the callback has not been installed when the > mainloop starts. But any subsequent interaction with the list > (clicking) will print it (since the callback is then setup). > > HTH Thanks for your reply. However, please see the example below, which is more like my actual use-case. The selection events take place when a button is pressed, after the mainloop has started but before the binding. This also prints 'called' three times.? from tkinter import * from tkinter.ttk import * class Test: def __init__(self): root=Tk() self.tree = Treeview(root) self.tree.pack() self.iid = self.tree.insert('', 0, text='test') Button(root, command=self.temp_unbind).pack() mainloop() def callback(self, *e): print('called') def temp_unbind(self): self.tree.unbind('<>') self.tree.selection_set(self.iid) self.tree.selection_remove(self.iid) self.tree.selection_set(self.iid) self.tree.bind('<>', self.callback) #self.tree.after(0, lambda: self.tree.bind('<>', self.callback)) c=Test() It seems the events are still queued, and then processed by a later bind? However, your solution still works, i.e. replacing the bind call with the commented line. This works even with a delay of 0, as suggested in Rob Cliffe's reply. Does the call to after clear the event queue somehow? My issue is solved, but I'm still curious about what is happening here. Regards John From python at mrabarnett.plus.com Tue Sep 12 10:59:42 2023 From: python at mrabarnett.plus.com (MRAB) Date: Tue, 12 Sep 2023 15:59:42 +0100 Subject: Tkinter ttk Treeview binding responds to past events! In-Reply-To: References: <084a1cfa-8889-3acd-d19c-8f204c314b7b@googlemail.com> Message-ID: <0f254651-44cd-ec88-4eaa-842a05ab1008@mrabarnett.plus.com> On 2023-09-12 06:43, John O'Hagan via Python-list wrote: > On Mon, 2023-09-11 at 22:25 +0200, Mirko via Python-list wrote: >> Am 11.09.23 um 14:30 schrieb John O'Hagan via Python-list: >> > I was surprised that the code below prints 'called' three times. >> > >> > >> > from tkinter import * >> > from tkinter.ttk import * >> > >> > root=Tk() >> > >> > def callback(*e): >> > ?? ? print('called') >> > >> > tree = Treeview(root) >> > tree.pack() >> > >> > iid = tree.insert('', 0, text='test') >> > >> > tree.selection_set(iid) >> > tree.selection_remove(iid) >> > tree.selection_set(iid) >> > >> > tree.bind('<>', callback) >> > >> > mainloop() >> > >> > In other words, selection events that occurred _before_ the >> > callback >> > function was bound to the Treeview selections are triggering the >> > function upon binding. AFAIK, no other tk widget/binding >> > combination >> > behaves this way (although I haven't tried all of them). >> > >> > This was a problem because I wanted to reset the contents of the >> > Treeview without triggering a relatively expensive bound function, >> > but >> > found that temporarily unbinding didn't prevent the calls. >> > >> > I've worked around this by using a regular button-click binding for >> > selection instead, but I'm curious if anyone can cast any light on >> > this. >> > >> > Cheers >> > >> > John >> >> >> AFAIK (it's been quite some time, since I used Tk/Tkinter): >> >> These selection events are not triggered upon binding, but after the >> mainloop has startet. Tk's eventloop is queue-driven, so the >> tree.selection_{set,remove}() calls just place the events on the >> queue. After that, you setup a callback and when the mainloop >> starts, it processes the events from the queue, executing the >> registered callback. >> >> I seem to remember, that I solved a similar issue by deferring the >> callback installation using root.after(). >> >> >> from tkinter import * >> from tkinter.ttk import * >> >> root=Tk() >> >> def callback(*e): >> ???? print('called') >> >> tree = Treeview(root) >> tree.pack() >> >> iid = tree.insert('', 0, text='test') >> >> tree.selection_set(iid) >> tree.selection_remove(iid) >> tree.selection_set(iid) >> >> root.after(100, lambda: tree.bind('<>', callback)) >> >> mainloop() >> >> >> >> This does not print "called" at all after startup (but still selects >> the entry), because the callback has not been installed when the >> mainloop starts. But any subsequent interaction with the list >> (clicking) will print it (since the callback is then setup). >> >> HTH > > > Thanks for your reply. However, please see the example below, which is > more like my actual use-case. The selection events take place when a > button is pressed, after the mainloop has started but before the > binding. This also prints 'called' three times. > > from tkinter import * > from tkinter.ttk import * > > class Test: > > def __init__(self): > root=Tk() > self.tree = Treeview(root) > self.tree.pack() > self.iid = self.tree.insert('', 0, text='test') > Button(root, command=self.temp_unbind).pack() > mainloop() > > def callback(self, *e): > print('called') > > def temp_unbind(self): > self.tree.unbind('<>') > self.tree.selection_set(self.iid) > self.tree.selection_remove(self.iid) > self.tree.selection_set(self.iid) > self.tree.bind('<>', self.callback) > #self.tree.after(0, lambda: self.tree.bind('<>', > self.callback)) > > c=Test() > > It seems the events are still queued, and then processed by a later > bind? > > However, your solution still works, i.e. replacing the bind call with > the commented line. This works even with a delay of 0, as suggested in > Rob Cliffe's reply. Does the call to after clear the event queue > somehow? > > My issue is solved, but I'm still curious about what is happening here. > Yes, it's still queuing the events. When an event occurs, it's queued. So, you unbound and then re-bound the callback in temp_unbind? Doesn't matter. All that matters is that on returning from temp_unbind to the main event loop, there are events queued and there's a callback registered, so the callback is invoked. Using the .after trick queues an event that will re-bind the callback _after_ the previous events have been handled. From mirkok.lists at googlemail.com Tue Sep 12 14:51:24 2023 From: mirkok.lists at googlemail.com (Mirko) Date: Tue, 12 Sep 2023 20:51:24 +0200 Subject: Tkinter ttk Treeview binding responds to past events! In-Reply-To: References: <084a1cfa-8889-3acd-d19c-8f204c314b7b@googlemail.com> Message-ID: Am 12.09.23 um 07:43 schrieb John O'Hagan via Python-list: > My issue is solved, but I'm still curious about what is happening here. MRAB already said it: When you enter the callback function, Tk's mainloop waits for it to return. So what's happening is: 1. Tk's mainloop pauses 2. temp_unbind() is called 3. TreeviewSelect is unbound 4. events are queued 5. TreeviewSelect is bound again 6. temp_unbind() returns 7. Tk's mainloop continues with the state: - TreeviewSelect is bound - events are queued Am 11.09.23 um 23:58 schrieb Rob Cliffe: > Indeed. And you don't need to specify a delay of 100 milliseconds. 0 will work (I'm guessing that's because queued actions are performed in the order that they were queued). Ah, nice, didn't know that! > I have also found that after() is a cure for some ills, though I > avoid using it more than I have to because it feels ... a bit > fragile, perhaps. Yeah. Though for me it was the delay which made it seem fragile. With a 0 delay, this looks much more reliable. FWIW, here's a version without after(), solving this purely on the python side, not by temporarily unbinding the event, but by selectively doing nothing in the callback function. from tkinter import * from tkinter.ttk import * class Test: def __init__(self): self.inhibit = False root=Tk() self.tree = Treeview(root) self.tree.pack() self.iid = self.tree.insert('', 0, text='test') Button(root, command=self.temp_inhibit).pack() mainloop() def callback(self, *e): if not self.inhibit: print('called') def temp_inhibit(self): self.inhibit = True self.tree.selection_set(self.iid) self.tree.selection_remove(self.iid) self.tree.selection_set(self.iid) self.inhibit = False self.callback() c=Test() HTH and regards From python at mrabarnett.plus.com Tue Sep 12 15:55:33 2023 From: python at mrabarnett.plus.com (MRAB) Date: Tue, 12 Sep 2023 20:55:33 +0100 Subject: Tkinter ttk Treeview binding responds to past events! In-Reply-To: References: <084a1cfa-8889-3acd-d19c-8f204c314b7b@googlemail.com> Message-ID: <822d5e73-5d9b-3465-33f5-e5ac28846b0d@mrabarnett.plus.com> On 2023-09-12 19:51, Mirko via Python-list wrote: > Am 12.09.23 um 07:43 schrieb John O'Hagan via Python-list: > >> My issue is solved, but I'm still curious about what is happening here. > > MRAB already said it: When you enter the callback function, Tk's > mainloop waits for it to return. So what's happening is: > > 1. Tk's mainloop pauses > 2. temp_unbind() is called > 3. TreeviewSelect is unbound > 4. events are queued > 5. TreeviewSelect is bound again > 6. temp_unbind() returns > 7. Tk's mainloop continues with the state: > - TreeviewSelect is bound > - events are queued > > Am 11.09.23 um 23:58 schrieb Rob Cliffe: > >> Indeed. And you don't need to specify a delay of 100 milliseconds. 0 will work (I'm guessing that's because queued actions are performed in the order that they were queued). > > Ah, nice, didn't know that! > Well, strictly speaking, it's the order in which they were queued except for .after, which will be postponed if you specify a positive delay. [snip] From rob.cliffe at btinternet.com Tue Sep 12 18:09:23 2023 From: rob.cliffe at btinternet.com (Rob Cliffe) Date: Tue, 12 Sep 2023 23:09:23 +0100 Subject: Tkinter ttk Treeview binding responds to past events! In-Reply-To: References: <084a1cfa-8889-3acd-d19c-8f204c314b7b@googlemail.com> Message-ID: <0723e913-c3cd-c49e-c891-a613228ad839@btinternet.com> On 12/09/2023 19:51, Mirko via Python-list wrote: > > >> I have also found that after() is a cure for some ills, though I >> avoid using it more than I have to because it feels ... a bit >> fragile, perhaps. > Yeah. Though for me it was the delay which made it seem fragile. With > a 0 delay, this looks much more reliable. > At one point I found myself writing, or thinking of writing, this sort of code ??? after(1, DoSomeThing) ??? after(2, Do SomeThingElse) ??? after(3, DoAThirdThing) ??? ... but this just felt wrong (is it reliable if some Things take more than a millisecond?? It may well be; I don't know), and error-prone if I want to add some more Things. Rob Cliffe From research at johnohagan.com Tue Sep 12 19:40:31 2023 From: research at johnohagan.com (John O'Hagan) Date: Wed, 13 Sep 2023 09:40:31 +1000 Subject: Tkinter ttk Treeview binding responds to past events! In-Reply-To: References: <084a1cfa-8889-3acd-d19c-8f204c314b7b@googlemail.com> Message-ID: On Tue, 2023-09-12 at 20:51 +0200, Mirko via Python-list wrote: > Am 12.09.23 um 07:43 schrieb John O'Hagan via Python-list: > > > My issue is solved, but I'm still curious about what is happening > > here. > > MRAB already said it: When you enter the callback function, Tk's > mainloop waits for it to return. So what's happening is: > > 1. Tk's mainloop pauses > 2. temp_unbind() is called > 3. TreeviewSelect is unbound > 4. events are queued > 5. TreeviewSelect is bound again > 6. temp_unbind() returns > 7. Tk's mainloop continues with the state: > - TreeviewSelect is bound > - events are queued > > [. . .] Thanks (also to others who have explained), now I get it! > FWIW, here's a version without after(), solving this purely on the? > python side, not by temporarily unbinding the event, but by > selectively doing nothing in the callback function. > > from tkinter import * > from tkinter.ttk import * > > class Test: > ???? def __init__(self): > ???????? self.inhibit = False > ???????? root=Tk() > ???????? self.tree = Treeview(root) > ???????? self.tree.pack() > ???????? self.iid = self.tree.insert('', 0, text='test') > ???????? Button(root, command=self.temp_inhibit).pack() > ???????? mainloop() > > ???? def callback(self, *e): > ???????? if not self.inhibit: > ???????????? print('called') > > ???? def temp_inhibit(self): > ???????? self.inhibit = True > ???????? self.tree.selection_set(self.iid) > ???????? self.tree.selection_remove(self.iid) > ???????? self.tree.selection_set(self.iid) > ???????? self.inhibit = False > ???????? self.callback() > > c=Test() > I like this solution better - it's much more obvious to me what it's doing. Regards John From python at mrabarnett.plus.com Tue Sep 12 20:33:27 2023 From: python at mrabarnett.plus.com (MRAB) Date: Wed, 13 Sep 2023 01:33:27 +0100 Subject: Tkinter ttk Treeview binding responds to past events! In-Reply-To: References: <084a1cfa-8889-3acd-d19c-8f204c314b7b@googlemail.com> Message-ID: On 2023-09-13 00:40, John O'Hagan via Python-list wrote: > On Tue, 2023-09-12 at 20:51 +0200, Mirko via Python-list wrote: >> Am 12.09.23 um 07:43 schrieb John O'Hagan via Python-list: >> >> > My issue is solved, but I'm still curious about what is happening >> > here. >> >> MRAB already said it: When you enter the callback function, Tk's >> mainloop waits for it to return. So what's happening is: >> >> 1. Tk's mainloop pauses >> 2. temp_unbind() is called >> 3. TreeviewSelect is unbound >> 4. events are queued >> 5. TreeviewSelect is bound again >> 6. temp_unbind() returns >> 7. Tk's mainloop continues with the state: >> - TreeviewSelect is bound >> - events are queued >> >> [. . .] > > Thanks (also to others who have explained), now I get it! > > >> FWIW, here's a version without after(), solving this purely on the >> python side, not by temporarily unbinding the event, but by >> selectively doing nothing in the callback function. >> >> from tkinter import * >> from tkinter.ttk import * >> >> class Test: >> ???? def __init__(self): >> ???????? self.inhibit = False >> ???????? root=Tk() >> ???????? self.tree = Treeview(root) >> ???????? self.tree.pack() >> ???????? self.iid = self.tree.insert('', 0, text='test') >> ???????? Button(root, command=self.temp_inhibit).pack() >> ???????? mainloop() >> >> ???? def callback(self, *e): >> ???????? if not self.inhibit: >> ???????????? print('called') >> >> ???? def temp_inhibit(self): >> ???????? self.inhibit = True >> ???????? self.tree.selection_set(self.iid) >> ???????? self.tree.selection_remove(self.iid) >> ???????? self.tree.selection_set(self.iid) >> ???????? self.inhibit = False >> ???????? self.callback() >> >> c=Test() >> > > > I like this solution better - it's much more obvious to me what it's > doing. > That code is not binding at all, it's just calling 'temp_inhibit' when the button is clicked. You can remove all uses of self.inhibit and rename 'temp_inhibit' to something more meaningful, like 'delete_item'. From research at johnohagan.com Tue Sep 12 21:50:18 2023 From: research at johnohagan.com (John O'Hagan) Date: Wed, 13 Sep 2023 11:50:18 +1000 Subject: Tkinter ttk Treeview binding responds to past events! In-Reply-To: References: <084a1cfa-8889-3acd-d19c-8f204c314b7b@googlemail.com> Message-ID: <21d8117594218270b7e1b13d61ed9933f974c860.camel@johnohagan.com> On Wed, 2023-09-13 at 01:33 +0100, MRAB via Python-list wrote: > On 2023-09-13 00:40, John O'Hagan via Python-list wrote: > > On Tue, 2023-09-12 at 20:51 +0200, Mirko via Python-list wrote: > > > Am 12.09.23 um 07:43 schrieb John O'Hagan via Python-list: > > > [...] > > > > > > > FWIW, here's a version without after(), solving this purely on > > > the > > > python side, not by temporarily unbinding the event, but by > > > selectively doing nothing in the callback function. > > > > > > from tkinter import * > > > from tkinter.ttk import * > > > > > > class Test: > > > ???? def __init__(self): > > > ???????? self.inhibit = False > > > ???????? root=Tk() > > > ???????? self.tree = Treeview(root) > > > ???????? self.tree.pack() > > > ???????? self.iid = self.tree.insert('', 0, text='test') > > > ???????? Button(root, command=self.temp_inhibit).pack() > > > ???????? mainloop() > > > > > > ???? def callback(self, *e): > > > ???????? if not self.inhibit: > > > ???????????? print('called') > > > > > > ???? def temp_inhibit(self): > > > ???????? self.inhibit = True > > > ???????? self.tree.selection_set(self.iid) > > > ???????? self.tree.selection_remove(self.iid) > > > ???????? self.tree.selection_set(self.iid) > > > ???????? self.inhibit = False > > > ???????? self.callback() > > > > > > c=Test() > > > > > > > > > I like this solution better - it's much more obvious to me what > > it's > > doing. > > > That code is not binding at all, it's just calling 'temp_inhibit' > when > the button is clicked. > > You can remove all uses of self.inhibit and rename 'temp_inhibit' to > something more meaningful, like 'delete_item'. You're right of course, not as obvious as I thought! From jckeeler at alaska.edu Wed Sep 13 23:39:05 2023 From: jckeeler at alaska.edu (Jacob Keeler) Date: Wed, 13 Sep 2023 19:39:05 -0800 Subject: Python 3.11.5 Pip Issue Message-ID: I downloaded Python 3.11.5, and there was nothing in the ?Scripts? file, and there was no Pip. I would like to know why. Thank you, Jacob From skip.montanaro at gmail.com Thu Sep 14 08:55:39 2023 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Thu, 14 Sep 2023 07:55:39 -0500 Subject: Python 3.11.5 Pip Issue In-Reply-To: References: Message-ID: > I downloaded Python 3.11.5, and there was nothing in the ?Scripts? file, > and there was no Pip. I would like to know why. > Can't help with the empty/missing Scripts folder. Does running python -m ensurepip get you a working pip? Which you should then run as python -m pip ... Skip > From list1 at tompassin.net Thu Sep 14 09:30:54 2023 From: list1 at tompassin.net (Thomas Passin) Date: Thu, 14 Sep 2023 09:30:54 -0400 Subject: Python 3.11.5 Pip Issue In-Reply-To: References: Message-ID: <0424c77a-e197-77cf-599d-8cfafc2e1465@tompassin.net> On 9/13/2023 11:39 PM, Jacob Keeler via Python-list wrote: > I downloaded Python 3.11.5, and there was nothing in the ?Scripts? file, > and there was no Pip. I would like to know why. What do you mean by "downloaded"? And are you talking about Windows? Did you download the installer from python.org and run it, or did you download a zip file and unpack it? The answers will make a difference. From list1 at tompassin.net Thu Sep 14 10:41:39 2023 From: list1 at tompassin.net (Thomas Passin) Date: Thu, 14 Sep 2023 10:41:39 -0400 Subject: Python 3.11.5 Pip Issue In-Reply-To: References: Message-ID: On 9/13/2023 11:39 PM, Jacob Keeler via Python-list wrote: > I downloaded Python 3.11.5, and there was nothing in the ?Scripts? file, > and there was no Pip. I would like to know why. I just downloaded the 3.11.5 64-bit installer for Windows from python.org and ran it. This was an upgrade since I already had 3.11.4 installed. I had installed for me as a user rather than for "everyone" so it installed into %USERPROFILE%\AppData\Local\Programs\Python\Python311\. The Scripts folder is at C:\Users\tom\AppData\Local\Programs\Python\Python311\Scripts I checked and the installer did update the pip.exe and pip3.exe files. in this Scripts directory. So ... presumably you downloaded and ran the Windows 64-bit installer, is that right? Did you install it for "everyone" or just for you? Did you notice any error messages during installation? Did you do a standard install or did you customize it in some way? Exactly where is the "Scripts" directory in which you found "nothing"? Was the "py" launcher installed - that is, can you run Python 3.11.5 by typing "py"? If so, can you run pip by typing py -m pip (this is the most reliable way to run pip, by the way, because it always runs the version of pip that is installed for the latest install of Python). From scruelt at hotmail.com Fri Sep 15 06:49:10 2023 From: scruelt at hotmail.com (scruel tao) Date: Fri, 15 Sep 2023 10:49:10 +0000 Subject: Why doc call `__init__` as a method rather than function? Message-ID: ```python >>> class A: ... def __init__(self): ... pass ... >>> A.__init__ >>> a = A() >>> a.__init__ > ``` On many books and even the official documents, it seems that many authors prefer to call `__init__` as a "method" rather than a "function". The book PYTHON CRASH COURSE mentioned that "A function that?s part of a class is a method.", however, ` A.__init__` tells that `__init__` is a function... I wonder how can I call `__init__` as? Consider the output above. Maybe both are OK? If you prefer or think that we must use one of the two, please explain the why, I really want to know, thanks! From 2QdxY4RzWzUUiLuE at potatochowder.com Fri Sep 15 09:34:22 2023 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Fri, 15 Sep 2023 09:34:22 -0400 Subject: Why doc call `__init__` as a method rather than function? In-Reply-To: References: Message-ID: On 2023-09-15 at 10:49:10 +0000, scruel tao via Python-list wrote: > ```python > >>> class A: > ... def __init__(self): > ... pass > ... > >>> A.__init__ > > >>> a = A() > >>> a.__init__ > > > ``` > > On many books and even the official documents, it seems that many authors prefer to call `__init__` as a "method" rather than a "function". > The book PYTHON CRASH COURSE mentioned that "A function that?s part of a class is a method.", however, ` A.__init__` tells that `__init__` is a function... I always call __init__ "the initializer." YMMV. > I wonder how can I call `__init__` as? Consider the output above. > Maybe both are OK? If you prefer or think that we must use one of the two, please explain the why, I really want to know, thanks! Usually, you don't call (or even refer to) __init__ from your application. One __init__ can call another one in the case of initializing superclasses. When you evaluate A(), Python calls __init__ for you. You can see this if you add something "visible" to __init__, like a print statement. From c.buhtz at posteo.jp Fri Sep 15 10:15:23 2023 From: c.buhtz at posteo.jp (c.buhtz at posteo.jp) Date: Fri, 15 Sep 2023 14:15:23 +0000 Subject: PEP668 / pipx and "--editable" installs Message-ID: <988561df4bac884b3fe24b811b659946@posteo.de> Hello, I wonder that today was the first day I stumbled over PEP668 / pipx and the "externally-managed-environment" problem. I migrated from Debian 11 to 12. I'm developing some Python packages; applications and libraries. I never used virtual environments and wouldn't like to start with it. But I do use "--editable" for my packages. I wonder how I should go on with using "pipx" and "--editable" mode because I had some problems with it I couldn't fix following PEP668 but only with using "--break-system-packages". And PEP668 do not mention editable-mode. The two example packages I use here are public available and clonable (is this a word?) via git. Let's start with a command line application named "hyperorg" (https://codeberg.org/buhtz/hyperorg). I tried to install it via "pipx install -e .[develop]". It's pyproject.toml has a bug: A missing dependency "dateutil". But "dateutil" is not available from PyPi for Python 3.11 (the default in Debian 12). But thanks to great Debian they have a "python3-dateutil" package. I installed it. But "hyperorg" do ignore it and can't import it. Of course I re-installed hyperorg via pipx. Installing it via "pip" and "--break-system-packages" it works well and do see the "python3-dateutil" package. The second example is a "library" named "buhtzology" (https://codeberg.org/buhtz/buhtzology). Here it seems that "pipx" do refuse to install it in the first place ("pipx install -e .[develop]") and gave me this message. "No apps associated with package buhtzology. Try again with '--include-deps' to include apps of dependent packages, which are listed above. If you are attempting to install a library, pipx should not be used. Consider using pip or a similar tool instead." What is the difference between an "app" (it is a google/apple marketing term used for software with user interaction. Just name it application.) and a "library" in context of pip(x)? Why does it count? I tried again with "pipx install --include-deps -e .[develop]" and got an output I'm not sure if this is an error or a success message. I assume it is an error because I'm not able to "import buhtzology". It seems like that the package was not installed. ?? Note: normalizer was already on your PATH at /usr/bin/normalizer ?? Note: f2py was already on your PATH at /usr/bin/f2py ?? Note: f2py3 was already on your PATH at /usr/bin/f2py3 ?? Note: f2py3.11 was already on your PATH at /usr/bin/f2py3.11 ?? Note: py.test was already on your PATH at /usr/bin/py.test ?? Note: pytest was already on your PATH at /usr/bin/pytest ?? File exists at /home/user/.local/bin/pycodestyle and points to /home/user/.local/bin/pycodestyle, not /home/user/.local/pipx/venvs/buhtzology/bin/pycodestyle. Not modifying. ?? File exists at /home/user/.local/bin/ruff and points to /home/user/.local/bin/ruff, not /home/user/.local/pipx/venvs/buhtzology/bin/ruff. Not modifying. installed package buhtzology 0.2.0.dev0, installed using Python 3.11.2 These apps are now globally available - f2py - f2py3 - f2py3.11 - fonttools - normalizer - py.test - pyftmerge - pyftsubset - pytest - tabulate - ttx - pycodestyle (symlink missing or pointing to unexpected location) - ruff (symlink missing or pointing to unexpected location) done! ? ? ? BUT! $ python3 -c "import buhtzology" Traceback (most recent call last): File "", line 1, in ModuleNotFoundError: No module named 'buhtzology' From cspealma at redhat.com Fri Sep 15 11:16:32 2023 From: cspealma at redhat.com (Clara Spealman) Date: Fri, 15 Sep 2023 11:16:32 -0400 Subject: Why doc call `__init__` as a method rather than function? In-Reply-To: References: Message-ID: All methods are functions, but not all functions are methods. All methods are functions in the namespace of a class and when resolved from the class directly, you'll get the original function. Its only when resolved from an *instance* of the class, as in self.__init__ or self.any_other_method(), that the function is wrapped in a method object, which is callable and binds the function to the particular instance passed as "self". So the simple answer is "its both". The only slightly less simple answer is "its both, depending on how you're getting it." On Fri, Sep 15, 2023 at 6:53?AM scruel tao via Python-list < python-list at python.org> wrote: > ```python > >>> class A: > ... def __init__(self): > ... pass > ... > >>> A.__init__ > > >>> a = A() > >>> a.__init__ > > > ``` > > On many books and even the official documents, it seems that many authors > prefer to call `__init__` as a "method" rather than a "function". > The book PYTHON CRASH COURSE mentioned that "A function that?s part of a > class is a method.", however, ` A.__init__` tells that `__init__` is a > function... > > I wonder how can I call `__init__` as? Consider the output above. > Maybe both are OK? If you prefer or think that we must use one of the two, > please explain the why, I really want to know, thanks! > -- > https://mail.python.org/mailman/listinfo/python-list > > -- CALVIN SPEALMAN SENIOR QUALITY ENGINEER calvin.spealman at redhat.com M: +1.336.210.5107 [image: https://red.ht/sig] TRIED. TESTED. TRUSTED. From sjeik_appie at hotmail.com Fri Sep 15 11:42:06 2023 From: sjeik_appie at hotmail.com (Albert-Jan Roskam) Date: Fri, 15 Sep 2023 17:42:06 +0200 Subject: Postgresql equivalent of Python's timeit? Message-ID: Hi, This is more related to Postgresql than to Python, I hope this is ok. I want to measure Postgres queries N times, much like Python timeit (https://docs.python.org/3/library/timeit.html). I know about EXPLAIN ANALYZE and psql \timing, but there's quite a bit of variation in the times. Is there a timeit-like function in Postgresql? Thanks! Albert-Jan From hjp-python at hjp.at Fri Sep 15 13:45:16 2023 From: hjp-python at hjp.at (Peter J. Holzer) Date: Fri, 15 Sep 2023 19:45:16 +0200 Subject: Postgresql equivalent of Python's timeit? In-Reply-To: References: Message-ID: <20230915174516.2uliozlczlu7dxcq@hjp.at> On 2023-09-15 17:42:06 +0200, Albert-Jan Roskam via Python-list wrote: > This is more related to Postgresql than to Python, I hope this is ok. > I want to measure Postgres queries N times, much like Python timeit > (https://docs.python.org/3/library/timeit.html). I know about EXPLAIN > ANALYZE and psql \timing, but there's quite a bit of variation in the > times. Is there a timeit-like function in Postgresql? Why not simply call it n times from Python? (But be aware that calling the same query n times in a row is likely to be unrealistically fast because most of the data will already be in memory.) 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 learn2program at gmail.com Fri Sep 15 14:29:57 2023 From: learn2program at gmail.com (Alan Gauld) Date: Fri, 15 Sep 2023 19:29:57 +0100 Subject: Why doc call `__init__` as a method rather than function? In-Reply-To: References: Message-ID: On 15/09/2023 11:49, scruel tao via Python-list wrote: > ```python >>>> class A: > ... def __init__(self): > ... pass > On many books and even the official documents, it seems that > many authors prefer to call `__init__` as a "method" rather > than a "function". That' because in OOP terminology methods are traditionally implemented as functions defined inside a class (There are other ways to define methods in other languages, but the class/function duology is by far the most common.) What is a method? It is the way that an object handles a message. OOP is all about objects sending messages to each other. Many different objects can receive the same message but they each have their own method of handling that message. (This is called polymorphism.) Over time the most common way to implememt OOP in a language is to invent a "class" structure and to allow functions to either be defined within it or added to it later. In either case these functions are what define how a class (and its object instances) handle a given message. So the function describes the method for that message. And over time that has become shortened to the function inside a class *is* its method. In practice, the message looks like a function call. And the method consists of the function body (and/or any inherited function body). Thus every method is a function (or set of functions) but not every function is a method (or part of one). -- 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 rmlibre at riseup.net Fri Sep 15 17:48:37 2023 From: rmlibre at riseup.net (rmlibre at riseup.net) Date: Fri, 15 Sep 2023 21:48:37 +0000 Subject: `time.perf_counter_ns` always a 64-bit int? Message-ID: <199f0ab709fc733045089890d785d6a0@riseup.net> I'd like to capture the output of `time.perf_counter_ns()` as an 8-byte timestamp. I'm aware that the docs provide an undefined start value for that clock. I'm going to assume that means it can't be expected to fit within 8 bytes. However, it would be rather convenient if it could. Does anyone know if any such platform agnostic assumption could be made for any fixed number of bytes, even if it isn't exactly 8 bytes? From rimuatkinson at gmail.com Fri Sep 15 22:17:19 2023 From: rimuatkinson at gmail.com (Rimu Atkinson) Date: Sat, 16 Sep 2023 14:17:19 +1200 Subject: PEP668 / pipx and "--editable" installs In-Reply-To: References: <988561df4bac884b3fe24b811b659946@posteo.de> Message-ID: > > I never > used virtual environments and wouldn't like to start with it. There's your problem - everything else is a result of this. There is just no nice way to work with a combination of pypi, apt-get and system-wide python. Everyone uses virtual environments. Sorry. From c.buhtz at posteo.jp Sat Sep 16 02:44:38 2023 From: c.buhtz at posteo.jp (c.buhtz at posteo.jp) Date: Sat, 16 Sep 2023 06:44:38 +0000 Subject: PEP668 / pipx and "--editable" installs In-Reply-To: References: <988561df4bac884b3fe24b811b659946@posteo.de> Message-ID: <4RnhPQ0S6fz9rxM@submission02.posteo.de> Dear Rimu, thanks for your reply. I'm willing to learn for sure. On 2023-09-16 14:17 Rimu Atkinson via Python-list wrote: > There's your problem - everything else is a result of this. There is > just no nice way to work with a combination of pypi, apt-get and > system-wide python. > > Everyone uses virtual environments. It is nothing bad about using virtual environments but also not about not using them. In my own work I haven't see a use case where I needed them. And I expect that some day I'll encounter a use case for it. This here is not about pro and cons of virtual environments. Please explain how the two problems I explained are influenced by not using virtual environments. As I explained I tried to use "pipx" (the X at the end!) because it seems to be the recommended way today because of PEP668. And to my knowledge pipx do use a virtual environment in the back. Nice. But it did not work the way I expected. I don't say that pipx is wrong or buggy. I assume I misunderstood something in context of PEP668 and in the use of pipx. That is why I'm asking here. From barry at barrys-emacs.org Sat Sep 16 04:52:45 2023 From: barry at barrys-emacs.org (Barry) Date: Sat, 16 Sep 2023 09:52:45 +0100 Subject: `time.perf_counter_ns` always a 64-bit int? In-Reply-To: <199f0ab709fc733045089890d785d6a0@riseup.net> References: <199f0ab709fc733045089890d785d6a0@riseup.net> Message-ID: > On 15 Sep 2023, at 23:00, rmlibre--- via Python-list wrote: > > ?I'd like to capture the output of `time.perf_counter_ns()` as an 8-byte > timestamp. > > I'm aware that the docs provide an undefined start value for that clock. > I'm going to assume that means it can't be expected to fit within 8 > bytes. However, it would be rather convenient if it could. Does anyone > know if any such platform agnostic assumption could be made for any > fixed number of bytes, even if it isn't exactly 8 bytes? If you read the source code the value is stored in a 64 bit int for unix and windows. There is a comment that it covers the range of +-232 years. Barry > -- > https://mail.python.org/mailman/listinfo/python-list > From Karsten.Hilbert at gmx.net Sat Sep 16 06:09:21 2023 From: Karsten.Hilbert at gmx.net (Karsten Hilbert) Date: Sat, 16 Sep 2023 12:09:21 +0200 Subject: PEP668 / pipx and "--editable" installs In-Reply-To: References: <988561df4bac884b3fe24b811b659946@posteo.de> Message-ID: Am Sat, Sep 16, 2023 at 02:17:19PM +1200 schrieb Rimu Atkinson via Python-list: > Everyone uses virtual environments. Umm, like, no. Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B From hjp-python at hjp.at Sat Sep 16 08:28:20 2023 From: hjp-python at hjp.at (Peter J. Holzer) Date: Sat, 16 Sep 2023 14:28:20 +0200 Subject: `time.perf_counter_ns` always a 64-bit int? In-Reply-To: <199f0ab709fc733045089890d785d6a0@riseup.net> References: <199f0ab709fc733045089890d785d6a0@riseup.net> Message-ID: <20230916122820.v2oleftj3bti3l4o@hjp.at> On 2023-09-15 21:48:37 +0000, rmlibre--- via Python-list wrote: > I'd like to capture the output of `time.perf_counter_ns()` as an 8-byte > timestamp. > > I'm aware that the docs provide an undefined start value for that clock. > I'm going to assume that means it can't be expected to fit within 8 > bytes. Theoretically this is true. The reference point could be the switch to the Gregorian calendar in the Vatican, the begin of the Christian era or the founding of Babylon, all of which were more than 2**63 seconds ago. However, using one of these dates would be impractical and defeat the purpose of the performance counters, which are supposed to be high resolution, monotonic and independent of political influences. So the reference point is usually the time the system was booted or something similar. > However, it would be rather convenient if it could. Unless you expect your system to have an uptime in excess of 292 years, don't worry. 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 sjeik_appie at hotmail.com Sun Sep 17 05:01:43 2023 From: sjeik_appie at hotmail.com (Albert-Jan Roskam) Date: Sun, 17 Sep 2023 11:01:43 +0200 Subject: Postgresql equivalent of Python's timeit? In-Reply-To: <20230915174516.2uliozlczlu7dxcq@hjp.at> Message-ID: On Sep 15, 2023 19:45, "Peter J. Holzer via Python-list" wrote: On 2023-09-15 17:42:06 +0200, Albert-Jan Roskam via Python-list wrote: >??? This is more related to Postgresql than to Python, I hope this is ok. >??? I want to measure Postgres queries N times, much like Python timeit >??? (https://docs.python.org/3/library/timeit.html). I know about EXPLAIN >??? ANALYZE and psql \timing, but there's quite a bit of variation in the >??? times. Is there a timeit-like function in Postgresql? Why not simply call it n times from Python? (But be aware that calling the same query n times in a row is likely to be unrealistically fast because most of the data will already be in memory.) ===== Thanks, I'll give this a shot. Hopefully the caching is not an issue if I don't re-use the same database connection. From avi.e.gross at gmail.com Sun Sep 17 11:48:46 2023 From: avi.e.gross at gmail.com (avi.e.gross at gmail.com) Date: Sun, 17 Sep 2023 11:48:46 -0400 Subject: Postgresql equivalent of Python's timeit? In-Reply-To: References: <20230915174516.2uliozlczlu7dxcq@hjp.at> Message-ID: <001e01d9e97e$722ad0e0$568072a0$@gmail.com> Timing things that are fairly simple is hard enough to do repeatedly, but when it involves access to slower media and especially to network connections to servers, the number of things that can change are enormous. There are all kinds of caching at various levels depending on your hardware and resource contention with other programs running here and there as well as on various network-like structures and busses or just hard disks. Asking for anything to be repeated multiple times in a row as a general rule can make your results seem slower or faster depending on too many factors including what else is running on your machine. I am wondering if an approach to running something N times that may average things out a bit is to simply put in a pause. Have your program wait a few minutes between attempts and perhaps even do other things within your loop that make it likely some of the resources you want not to be in a queue have a chance to be flushed as other things take their place. Obviously, a machine or system with lots of resources may take more effort to use enough new data that replaces the old. Good luck. Getting reliable numbers is no easy feat as someone else may have trouble duplicating the results with a somewhat different setup. -----Original Message----- From: Python-list On Behalf Of Albert-Jan Roskam via Python-list Sent: Sunday, September 17, 2023 5:02 AM To: Peter J. Holzer Cc: python-list at python.org Subject: Re: Postgresql equivalent of Python's timeit? On Sep 15, 2023 19:45, "Peter J. Holzer via Python-list" wrote: On 2023-09-15 17:42:06 +0200, Albert-Jan Roskam via Python-list wrote: > This is more related to Postgresql than to Python, I hope this is ok. > I want to measure Postgres queries N times, much like Python timeit > (https://docs.python.org/3/library/timeit.html). I know about EXPLAIN > ANALYZE and psql \timing, but there's quite a bit of variation in the > times. Is there a timeit-like function in Postgresql? Why not simply call it n times from Python? (But be aware that calling the same query n times in a row is likely to be unrealistically fast because most of the data will already be in memory.) ===== Thanks, I'll give this a shot. Hopefully the caching is not an issue if I don't re-use the same database connection. -- https://mail.python.org/mailman/listinfo/python-list From list1 at tompassin.net Sun Sep 17 12:23:07 2023 From: list1 at tompassin.net (Thomas Passin) Date: Sun, 17 Sep 2023 12:23:07 -0400 Subject: Postgresql equivalent of Python's timeit? In-Reply-To: <001e01d9e97e$722ad0e0$568072a0$@gmail.com> References: <20230915174516.2uliozlczlu7dxcq@hjp.at> <001e01d9e97e$722ad0e0$568072a0$@gmail.com> Message-ID: <4d367518-c137-84df-4ae0-4489bb6639a5@tompassin.net> On 9/17/2023 11:48 AM, AVI GROSS via Python-list wrote: > Timing things that are fairly simple is hard enough to do repeatedly, but when it involves access to slower media and especially to network connections to servers, the number of things that can change are enormous. There are all kinds of caching at various levels depending on your hardware and resource contention with other programs running here and there as well as on various network-like structures and busses or just hard disks. Asking for anything to be repeated multiple times in a row as a general rule can make your results seem slower or faster depending on too many factors including what else is running on your machine. > > I am wondering if an approach to running something N times that may average things out a bit is to simply put in a pause. Have your program wait a few minutes between attempts and perhaps even do other things within your loop that make it likely some of the resources you want not to be in a queue have a chance to be flushed as other things take their place. One thing I have done for timing queries is to construct a series of test queries with the query parameters drawn randomly from a large set of values. The hope is that random combinations will defeat caching and provide a reasonably realistic view of the times. From hjp-python at hjp.at Sun Sep 17 12:34:17 2023 From: hjp-python at hjp.at (Peter J. Holzer) Date: Sun, 17 Sep 2023 18:34:17 +0200 Subject: Postgresql equivalent of Python's timeit? In-Reply-To: References: <20230915174516.2uliozlczlu7dxcq@hjp.at> Message-ID: <20230917163417.fo3ss5rq5a3b7phy@hjp.at> On 2023-09-17 11:01:43 +0200, Albert-Jan Roskam via Python-list wrote: > On Sep 15, 2023 19:45, "Peter J. Holzer via Python-list" > wrote: > > On 2023-09-15 17:42:06 +0200, Albert-Jan Roskam via Python-list wrote: > >??? This is more related to Postgresql than to Python, I hope this is > ok. > >??? I want to measure Postgres queries N times, much like Python timeit > >??? (https://docs.python.org/3/library/timeit.html). I know about > EXPLAIN > >??? ANALYZE and psql \timing, but there's quite a bit of variation in > the > >??? times. Is there a timeit-like function in Postgresql? > > Why not simply call it n times from Python? > > (But be aware that calling the same query n times in a row is likely to > be > unrealistically fast because most of the data will already be in > memory.) > > ===== > Thanks, I'll give this a shot. Hopefully the caching is not an issue if I > don't re-use the same database connection. There is some per-session caching, but the bulk of it is shared between sessions or even in the operating system. And you wouldn't want to get rid of these caches either (which you could do by rebooting or - a bit faster - restarting postgres and dropping the caches (/proc/sys/vm/drop_caches on Linux), because that would make the benchmark unrealistically slow (unless you want to establish some worst-case baseline). During normal operations some data will be cached, but probably not all of it and it will change depending on workload and possibly other factors. I think Avi's advice to wait for a few minutes between repetitions is good. Of course that means that you can't just time the whole thing but have to time each query separately and then compute the average. (On the bright side that also gives you the opportunity to compute standard deviation, min, max, quantiles, etc.) 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 list1 at tompassin.net Sun Sep 17 08:52:30 2023 From: list1 at tompassin.net (Thomas Passin) Date: Sun, 17 Sep 2023 08:52:30 -0400 Subject: Postgresql equivalent of Python's timeit? In-Reply-To: References: Message-ID: On 9/17/2023 5:01 AM, Albert-Jan Roskam via Python-list wrote: > On Sep 15, 2023 19:45, "Peter J. Holzer via Python-list" > wrote: > > On 2023-09-15 17:42:06 +0200, Albert-Jan Roskam via Python-list wrote: > >??? This is more related to Postgresql than to Python, I hope this is > ok. > >??? I want to measure Postgres queries N times, much like Python timeit > >??? (https://docs.python.org/3/library/timeit.html). I know about > EXPLAIN > >??? ANALYZE and psql \timing, but there's quite a bit of variation in > the > >??? times. Is there a timeit-like function in Postgresql? > > Why not simply call it n times from Python? > > (But be aware that calling the same query n times in a row is likely to > be > unrealistically fast because most of the data will already be in > memory.) > > ===== > Thanks, I'll give this a shot. Hopefully the caching is not an issue if I > don't re-use the same database connection. Here is a stack overflow thread that gives a good rundown of ways to get timings from Postgres: https://stackoverflow.com/questions/9063402/get-execution-time-of-postgresql-query From meowxiik at gmail.com Sat Sep 16 04:17:20 2023 From: meowxiik at gmail.com (Meowxiik) Date: Sat, 16 Sep 2023 10:17:20 +0200 Subject: Confusing behavior of PYTHONWARNINGS Message-ID: Hello, For the third time I am trying to work with `PYTHONWARNINGS` filter, and for the third time I am having a terrible time. I'd like to seek your assistance, I have a few questions: **Question 1:** Does the environment variable only matter at python interpreter startup time? If I set the same variable before python start, it seems to work, but it doesn't work trough os.environ. It does appear to be hinted at in the docs, but imho not clear enough. **Question 2:** Why do the following filters not work for filtering `urllib3.exceptions.InsecureRequestWarning` - `PYTHONWARNINGS=ignore:::urllib3.exceptions` - `PYTHONWARNINGS=ignore:::urllib3` - `PYTHONWARNINGS=ignore:::urllib3.exceptions` - `PYTHONWARNINGS=ignore::urllib3.exceptions.InsecureRequestWarning` None of these filter the warning. The last one has the audacity to complain about "invalid module name: 'urllib3.exceptions'" which is very confusing to me, given that that specific module is fully importable during runtime, which I have tested. The only one I managed to get working is `ignore:Unverified`, where "Unverified" is the first word of the actual message, however I truly strongly dislike this solution. Thank you for any help, Richard From aerusso at aerusso.net Sat Sep 16 12:49:42 2023 From: aerusso at aerusso.net (Antonio Russo) Date: Sat, 16 Sep 2023 10:49:42 -0600 Subject: subprocess: TTYs and preexec_fn Message-ID: Hello! I'm trying to run a subprocess (actually several), and control their terminals (not just stdin and stdout). I have a use case, but I won't bore everyone with those details. I'd rather not use pexpect or ptyprocess, because those expose a very different interface than Popen. I've mostly acheived my goals with the following wrapper around subprocess: > import subprocess, pty, fcntl, termios, os > TTY = 'termyTTY' > > def Popen(cmd, **kwargs): > tty = kwargs.pop('tty', None) > if tty is not None: > if tty is True: > tty = pty.openpty() > master_fd, slave_fd = tty > old_preexec = kwargs.get('preexec_fn') > def preexec_fn(): > if old_preexec: > old_preexec() > fcntl.ioctl(slave_fd, termios.TIOCSCTTY) > kwargs['preexec_fn'] = preexec_fn > kwargs['start_new_session'] = True > for stkind in ('stdin', 'stdout', 'stderr'): > if kwargs.get(stkind, None) != TTY: > continue > kwargs[stkind] = slave_fd > > proc = subprocess.Popen(cmd, **kwargs) > if tty is not None: > proc.tty = master_fd > os.close(slave_fd) > return proc This adds a tty keyword argument that spawns a new controlling TTY and switches the new process to it. It also allows setting stdin/etc. separately. You can, for instance, run ssh and send it a password through the tty channel, and separately receive piped output from the remote ssh command. My questions: 1. Is this already available in a simple way somewhere else, preferably with a Popen-compatible interface? 2. Is this preexec_fn sufficiently simple that it does not run afoul of the big, scary threading warning of _posixsubprocess.fork_exec ? I.e., I'm not touching any locks (besides the GIL... but I'm assuming that would be properly handled?). CAN this be made safe? I do plan to use threads and locks. 3. Does this seem widely useful enough to be worth trying to get into Python itself? It would be nice if this specific behavior, which probably has even more nuances than I already am aware of, were safely achievable out of the box. Best, Antonio From cooler9.t at icloud.com Sat Sep 16 21:20:56 2023 From: cooler9.t at icloud.com (James Greenham) Date: Sun, 17 Sep 2023 04:20:56 +0300 Subject: Python Launcher Pops Up When Py-based App Is Running (Mac) Message-ID: Hello, On the face of it, the Python-Mac mailing list is largely inactive so I'm posting here since it looks like this one is livelier. I'm running macOS Mojave with Python 2.7. I have an old Dashboard widget (last modified in 2009) that appears to use Python as well. The widget captures the full Safari web-page. It works seamlessly on earlier macOS systems but hangs in 10.14. The widget's core functions constitute code of the script that I'm pasting in this message. The problem is that as soon as the execution reaches the image processing stage it gets stuck which manifests by Python Launcher popping up in Dock and is trying forever until I quit the launcher that force-quits the widget showing the error icon. The issue seems to originate in the doGrab handler (module or whatever the correct Python term fits the definition) immediately following the print "Processing Image..." line: it's the message the widget displays at getting stalled. I( checked that Python 2.7 is installed in the default location at /usr/bin. I also have the binaries idle3, idle3.10, pip3, pip3.10 in /usr/local/bin, apparently used by another Unix program. Is that remedied? The script's environment set to python, i.e. to python 2.7 so that shouldn't be the encumbrance. Am I correct? #!/usr/bin/env python # -*- coding: utf-8 -*- # OR: # coding=utf-8 __version__ = "0.6" # # Based on Paul Hammond's webkit2png script - make screenshots of webpages # http://www.paulhammond.org/webkit2png # # Modified by Paulo Avila for the Page Capture widget # # The original source code (v0.5) belongs to Paul Hammond (see notice below). # Any and all code added after is Copyright (c) 2009 Paulo Avila. # # Modification Log by Paul Avila # # 2009.04.21 - Changed almost all the output messages in order to behave properly with my Page Capture widget # 2009.04.21 - Added function headers # 2009.04.21 - Properly flush the output buffers so that messages display immediately # 2009.04.21 - Changed encoding of this file to UTF-8 # 2009.04.25 - Updated how files are named: " > .png" # 2009.04.25 - Files are now named with the full URL excluding protocol (http://) and arguments (...?*) # # Copyright (c) 2009 Paul Hammond # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # import sys import optparse try: import Foundation import WebKit import AppKit import objc except ImportError: #print "Cannot find pyobjc library files. Are you sure it is installed?" print "Mac OS X 10.5 or higher is required." sys.stdout.flush() sys.exit() class AppDelegate (Foundation.NSObject): # what happens when the app starts up def applicationDidFinishLaunching_(self, aNotification): webview = aNotification.object().windows()[0].contentView() webview.frameLoadDelegate().getURL(webview) class WebkitLoad (Foundation.NSObject, WebKit.protocols.WebFrameLoadDelegate): # what happens if something goes wrong while loading def webView_didFailLoadWithError_forFrame_(self,webview,error,frame): #print " ... something went wrong" print "Unable to load WebKit." sys.stdout.flush() self.getURL(webview) def webView_didFailProvisionalLoadWithError_forFrame_(self,webview,error,frame): #print " ... something went wrong" print "Check URL or Internet connection." sys.stdout.flush() self.getURL(webview) #--------------------------------------------------- #7 - Generates the filename. def makeFilename(self,URL,options): # make the filename if options.filename: filename = options.filename elif options.md5: try: import md5 except ImportError: print "--md5 requires python md5 library" sys.stdout.flush() AppKit.NSApplication.sharedApplication().terminate_(None) filename = md5.new(URL).hexdigest() else: import re # filename = re.sub('\W','',URL); #\W is the same as [^a-zA-Z0-9_] #-------- #remove anything after (and including) a question mark URL = re.sub("\?.*$", "", URL); #arg = URL.find("?"); #if arg >= 0: # URL = URL[0:arg]; #remove the protocol string in the beginning (SSL or not) URL = re.sub("^https?://", "", URL); #-- Page Capture # (start) import os dir = os.path.abspath(os.path.expanduser(options.dir)); count = 1; while os.access(dir + "/Page Capture " + str(count) + ".png", os.F_OK): count += 1; filename = "Page Capture " + str(count); #-- Page Capture # (end) #-- Full URL (start) #replace forward slashes with colons to allow to forward slashes in the filename (OS X's HFS+ allows for this) # filename = re.sub("/", ":", URL); #max filename length permitted is 255. (255 - 4 = 251). (4 is the length of the extenion '.png') # if len(filename) > 251: # filename = filename[0:248] + "..."; #-- Full URL (end) #-- Domain > File (start) # URL = URL.split("/"); #isolate just the domain # domain = URL[0]; #domain = re.sub("/.*$", "", URL); #domain = URL[0:URL.find("/")]; #isolate just the file, if it doesn't exist, make it blank # file = URL[len(URL)-1]; # if len(URL) == 1: # file = ""; # filename = domain + " > " + file; #print "d= '" + domain + "'"; #print "f= '" + file + "'"; #-- Domain > File (end) #-------- if options.datestamp: import time now = time.strftime("%Y%m%d") # now = time.strftime("%Y%m%d%H%M%S") filename = now + "-" + filename # import os # dir = os.path.abspath(os.path.expanduser(options.dir)) # return os.path.join(dir,filename) return filename #--------------------------------------------------- #8 - Saves the captured image(s) to the right place. def saveImages(self,bitmapdata,filename,options): # save the fullsize png if options.fullsize: bitmapdata.representationUsingType_properties_(AppKit.NSPNGFileType,None).writeToFile_atomically_(filename + "-full.png",objc.YES) if options.thumb or options.clipped: # work out how big the thumbnail is width = bitmapdata.pixelsWide() height = bitmapdata.pixelsHigh() thumbWidth = (width * options.scale) thumbHeight = (height * options.scale) # make the thumbnails in a scratch image scratch = AppKit.NSImage.alloc().initWithSize_( Foundation.NSMakeSize(thumbWidth,thumbHeight)) scratch.lockFocus() AppKit.NSGraphicsContext.currentContext().setImageInterpolation_( AppKit.NSImageInterpolationHigh) thumbRect = Foundation.NSMakeRect(0.0, 0.0, thumbWidth, thumbHeight) clipRect = Foundation.NSMakeRect(0.0, thumbHeight-options.clipheight, options.clipwidth, options.clipheight) bitmapdata.drawInRect_(thumbRect) thumbOutput = AppKit.NSBitmapImageRep.alloc().initWithFocusedViewRect_(thumbRect) clipOutput = AppKit.NSBitmapImageRep.alloc().initWithFocusedViewRect_(clipRect) scratch.unlockFocus() # save the thumbnails as pngs if options.thumb: thumbOutput.representationUsingType_properties_( AppKit.NSPNGFileType,None ).writeToFile_atomically_(filename + ".png",objc.YES) # thumbOutput.representationUsingType_properties_( # AppKit.NSPNGFileType,None # ).writeToFile_atomically_(filename + "-thumb.png",objc.YES) if options.clipped: clipOutput.representationUsingType_properties_( AppKit.NSPNGFileType,None ).writeToFile_atomically_(filename + "-clipped.png",objc.YES) #--------------------------------------------------- #1 - Downloads URL contents. def getURL(self,webview): if self.urls: if self.urls[0] == '-': url = sys.stdin.readline().rstrip() if not url: AppKit.NSApplication.sharedApplication().terminate_(None) else: url = self.urls.pop(0) else: AppKit.NSApplication.sharedApplication().terminate_(None) #print "Fetching", url, "..." print "Fetching URL..." sys.stdout.flush() self.resetWebview(webview) webview.mainFrame().loadRequest_(Foundation.NSURLRequest.requestWithURL_(Foundation.NSURL.URLWithString_(url))) if not webview.mainFrame().provisionalDataSource(): #print " ... not a proper url?" print "Invalid URL." sys.stdout.flush() self.getURL(webview) #--------------------------------------------------- #2 - Resets any previous history? def resetWebview(self,webview): rect = Foundation.NSMakeRect(0,0,self.options.initWidth,self.options.initHeight) webview.window().setContentSize_((self.options.initWidth,self.options.initHeight)) webview.setFrame_(rect) #--------------------------------------------------- #5 - Resizes the window. def resizeWebview(self,view): view.window().display() view.window().setContentSize_(view.bounds().size) view.setFrame_(view.bounds()) #--------------------------------------------------- #6 - Turns current webview content into a bitmap. def captureView(self,view): view.lockFocus() bitmapdata = AppKit.NSBitmapImageRep.alloc() bitmapdata.initWithFocusedViewRect_(view.bounds()) view.unlockFocus() return bitmapdata #--------------------------------------------------- #3 - Called for each "piece" of the page. # what happens when the page has finished loading def webView_didFinishLoadForFrame_(self,webview,frame): # don't care about subframes if (frame == webview.mainFrame()): Foundation.NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_( self.options.delay, self, self.doGrab, webview, False) #--------------------------------------------------- #4 - Process the downloaded content (calls 5-8) def doGrab(self,timer): print "Processing image..." sys.stdout.flush() webview = timer.userInfo() view = webview.mainFrame().frameView().documentView() self.resizeWebview(view) URL = webview.mainFrame().dataSource().initialRequest().URL().absoluteString() filename = self.makeFilename(URL, self.options) import os full_path = os.path.join(os.path.abspath(os.path.expanduser(self.options.dir)), filename); bitmapdata = self.captureView(view) self.saveImages(bitmapdata, full_path, self.options) #print " ... done" # ? print "" + filename + " saved to your Desktop." sys.stdout.flush() self.getURL(webview) def main(): # parse the command line usage = """%prog [options] [http://example.net/ ...] examples: %prog http://google.com/ # screengrab google %prog -W 1000 -H 1000 http://google.com/ # bigger screengrab of google %prog -T http://google.com/ # just the thumbnail screengrab %prog -TF http://google.com/ # just thumbnail and fullsize grab %prog -o foo http://google.com/ # save images as "foo-thumb.png" etc %prog - # screengrab urls from stdin %prog -h | less # full documentation""" cmdparser = optparse.OptionParser(usage,version=("webkit2png "+__version__)) # TODO: add quiet/verbose options cmdparser.add_option("-W", "--width",type="float",default=800.0, help="initial (and minimum) width of browser (default: 800)") cmdparser.add_option("-H", "--height",type="float",default=600.0, help="initial (and minimum) height of browser (default: 600)") cmdparser.add_option("--clipwidth",type="float",default=200.0, help="width of clipped thumbnail (default: 200)", metavar="WIDTH") cmdparser.add_option("--clipheight",type="float",default=150.0, help="height of clipped thumbnail (default: 150)", metavar="HEIGHT") cmdparser.add_option("-s", "--scale",type="float",default=0.25, help="scale factor for thumbnails (default: 0.25)") cmdparser.add_option("-m", "--md5", action="store_true", help="use md5 hash for filename (like del.icio.us )") cmdparser.add_option("-o", "--filename", type="string",default="", metavar="NAME", help="save images as NAME-full.png,NAME-thumb.png etc") cmdparser.add_option("-F", "--fullsize", action="store_true", help="only create fullsize screenshot") cmdparser.add_option("-T", "--thumb", action="store_true", help="only create thumbnail sreenshot") cmdparser.add_option("-C", "--clipped", action="store_true", help="only create clipped thumbnail screenshot") cmdparser.add_option("-d", "--datestamp", action="store_true", help="include date in filename") cmdparser.add_option("-D", "--dir",type="string",default="./", help="directory to place images into") cmdparser.add_option("--delay",type="float",default=0, help="delay between page load finishing and screenshot") cmdparser.add_option("--noimages", action="store_true", help="don't load images") cmdparser.add_option("--debug", action="store_true", help=optparse.SUPPRESS_HELP) (options, args) = cmdparser.parse_args() if len(args) == 0: cmdparser.print_usage() return if options.filename: if len(args) != 1 or args[0] == "-": print "--filename option requires exactly one url" sys.stdout.flush() return if options.scale == 0: cmdparser.error("scale cannot be zero") # make sure we're outputing something if not (options.fullsize or options.thumb or options.clipped): options.fullsize = True options.thumb = True options.clipped = True # work out the initial size of the browser window # (this might need to be larger so clipped image is right size) options.initWidth = (options.clipwidth / options.scale) options.initHeight = (options.clipheight / options.scale) if options.width>options.initWidth: options.initWidth = options.width if options.height>options.initHeight: options.initHeight = options.height app = AppKit.NSApplication.sharedApplication() # create an app delegate delegate = AppDelegate.alloc().init() AppKit.NSApp().setDelegate_(delegate) # create a window rect = Foundation.NSMakeRect(0,0,100,100) win = AppKit.NSWindow.alloc() win.initWithContentRect_styleMask_backing_defer_ (rect, AppKit.NSBorderlessWindowMask, 2, 0) if options.debug: win.orderFrontRegardless() # create a webview object webview = WebKit.WebView.alloc() webview.initWithFrame_(rect) # turn off scrolling so the content is actually x wide and not x-15 webview.mainFrame().frameView().setAllowsScrolling_(objc.NO) webview.setPreferencesIdentifier_('webkit2png') webview.preferences().setLoadsImagesAutomatically_(not options.noimages) # add the webview to the window win.setContentView_(webview) # create a LoadDelegate loaddelegate = WebkitLoad.alloc().init() loaddelegate.options = options loaddelegate.urls = args webview.setFrameLoadDelegate_(loaddelegate) app.run() if __name__ == '__main__' : main() Best, James From rimuatkinson at gmail.com Sat Sep 16 19:57:41 2023 From: rimuatkinson at gmail.com (Rimu Atkinson) Date: Sun, 17 Sep 2023 11:57:41 +1200 Subject: PEP668 / pipx and "--editable" installs In-Reply-To: References: <988561df4bac884b3fe24b811b659946@posteo.de> <4RnhPQ0S6fz9rxM@submission02.posteo.de> Message-ID: > It is nothing bad about using virtual environments but also not about > not using them. In my own work I haven't see a use case where I needed > them. And I expect that some day I'll encounter a use case for it. This > here is not about pro and cons of virtual environments. > You are in a use case where you need them, right now :) When you understand the benefits of virtual environments you will understand what I meant by that. > Please explain how the two problems I explained are influenced by not > using virtual environments. The first problem can be avoided because virtual environments can use a different version of python than the system one. If you need an earlier version of python then you can use it instead. The second problem can be avoided because virtual environments exist in a part of the file system that you have write access to, so you don't need to use sudo to install packages. Your main user account does not have write access to /usr/bin. Also when a virtual environment is activated the path to it's packages is a part of that environment so your code will always be able to import the packages you want. It's much easier to understand if you try it for yourself. Google has many excellent resources, here is one https://www.freecodecamp.org/news/how-to-setup-virtual-environments-in-python/ Best of luck :) R From rimuatkinson+usenet at gmail.com Sun Sep 17 18:59:15 2023 From: rimuatkinson+usenet at gmail.com (Rimu Atkinson) Date: Mon, 18 Sep 2023 10:59:15 +1200 Subject: Async options for flask app Message-ID: Hi all, I'm writing a fediverse server app, similar to kbin https://kbin.pub/en and lemmy https://join-lemmy.org/. It's like reddit except anyone can run a server in the same way email works. This architecture involves a lot of inter-server communication, potentially involving thousands of different servers. So, lots of network I/O. Lots of tasks running in parallel to do I/O with different servers simultaneously. A fair bit of DB access too. The current fashion is to do this with cooperative multitasking (async/await/gevent/etc) to avoid the overhead associated with continually context switching threads and processes. Correct me if I'm wrong. How can I do this with Flask? Any async/await tricks? Can I just configure gunicorn to use gevent worker threads? https://flask.palletsprojects.com/en/2.3.x/deploying/gunicorn/ Has anyone tried Quart? https://pypi.org/project/quart/ How well does gevent monkey-patch into a Flask app? A penny for your thoughts Thanks! R From anthony.flury at btinternet.com Fri Sep 15 09:05:18 2023 From: anthony.flury at btinternet.com (anthony.flury) Date: Fri, 15 Sep 2023 14:05:18 +0100 (BST) Subject: Why doc call `__init__` as a method rather than function? In-Reply-To: References: Message-ID: <6a907429.54af.18a98f21d8d.Webtop.90@btinternet.com> To me __init__ is a method, but that is implemented internally as function associated to a class When you use A.__init__ on it's own and inspect it, then it will show that it is a function object - this is expected. The implementation internals of the runtime don't need to have a special implementation for a method. Like all of the other ____ methods you shouldn't ever need to call them directly : these are called dunder methods and represent functions and features which are called by other operators. The only recommended way to call A.__init__ is to create an instance of A : obj = A() - the __init__ method gets called automatically with a newly created object. If you did call A.__init__() directly on a an already existing object : obj = A() A.__init__(obj) for example - all that would happen is that the object itself would be reset : ie the obj's attributes would be reset to whatever the __init__ sets them to - if you need to do that it might be better to have a reset method. Regards, Tony ------ Original Message ------ From: "scruel tao via Python-list" To: "python-list at python.org" Sent: Friday, 15 Sep, 23 At 11:49 Subject: Why doc call `__init__` as a method rather than function? ```python class A: ... def __init__(self): ... pass ... A.__init__ a = A() a.__init__ > ``` On many books and even the official documents, it seems that many authors prefer to call `__init__` as a "method" rather than a "function". The book PYTHON CRASH COURSE mentioned that "A function that?s part of a class is a method.", however, ` A.__init__` tells that `__init__` is a function... I wonder how can I call `__init__` as? Consider the output above. Maybe both are OK? If you prefer or think that we must use one of the two, please explain the why, I really want to know, thanks! -- https://mail.python.org/mailman/listinfo/python-list --
Anthony Flury
anthony.flury at btinternet.com From rosuav at gmail.com Mon Sep 18 00:17:52 2023 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 18 Sep 2023 14:17:52 +1000 Subject: Async options for flask app In-Reply-To: References: Message-ID: On Mon, 18 Sept 2023 at 13:45, Rimu Atkinson via Python-list wrote: > > Hi all, > > I'm writing a fediverse server app, similar to kbin https://kbin.pub/en > and lemmy https://join-lemmy.org/. It's like reddit except anyone can > run a server in the same way email works. And the part you didn't say: It's like Reddit but without a ridiculous API fee. Right? :) > The current fashion is to do this with cooperative multitasking > (async/await/gevent/etc) to avoid the overhead associated with > continually context switching threads and processes. Correct me if I'm > wrong. I wouldn't say "current fashion", but yes, there is significant benefit in putting more than one task onto any given thread. (Most likely, if you want maximum throughput, you'll end up wanting a two-level multiplexer, with a pool of processes, each one managing a pool of tasks.) > How can I do this with Flask? Any async/await tricks? Can I just > configure gunicorn to use gevent worker threads? > https://flask.palletsprojects.com/en/2.3.x/deploying/gunicorn/ It's been a while since I did it, but it definitely does work, yes. > Has anyone tried Quart? https://pypi.org/project/quart/ Not me, so I'll let someone else answer that. > How well does gevent monkey-patch into a Flask app? > Here's one where I've done that: https://github.com/rosuav/mustardmine However, it's worth noting that (a) the exact details might differ depending on precisely what you use - this is backed by PostgreSQL and also uses websockets; and (b) I originally did this quite a while ago, and things may have gotten easier since then. All I know is, it works if I do it this way, and I haven't felt the urge to mess with that part of it. You may notice that my README mentions issues with Python 3.8 from back when that was new :) But with all of those caveats: Yes, this absolutely does work, and I make use of the Mustard Mine on a regular basis. It gets updates occasionally, not often, but I bump it onto newer Pythons every now and then, so the techniques it uses should still be valid. ChrisA From rosuav at gmail.com Mon Sep 18 00:18:31 2023 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 18 Sep 2023 14:18:31 +1000 Subject: Why doc call `__init__` as a method rather than function? In-Reply-To: <6a907429.54af.18a98f21d8d.Webtop.90@btinternet.com> References: <6a907429.54af.18a98f21d8d.Webtop.90@btinternet.com> Message-ID: On Mon, 18 Sept 2023 at 13:49, anthony.flury via Python-list wrote: > > > > To me __init__ is a method, but that is implemented internally as > function associated to a class > What is a method, if it is not a function associated with a class? ChrisA From list1 at tompassin.net Mon Sep 18 00:12:33 2023 From: list1 at tompassin.net (Thomas Passin) Date: Mon, 18 Sep 2023 00:12:33 -0400 Subject: PEP668 / pipx and "--editable" installs In-Reply-To: References: <988561df4bac884b3fe24b811b659946@posteo.de> <4RnhPQ0S6fz9rxM@submission02.posteo.de> Message-ID: <76285827-8def-bd62-94de-adf14326533c@tompassin.net> On 9/16/2023 7:57 PM, Rimu Atkinson via Python-list wrote: > >> It is nothing bad about using virtual environments but also not about >> not using them. In my own work I haven't see a use case where I needed >> them. And I expect that some day I'll encounter a use case for it. This >> here is not about pro and cons of virtual environments. >> > You are in a use case where you need them, right now :) When you > understand the benefits of virtual environments you will understand what > I meant by that. > >> Please explain how the two problems I explained are influenced by not >> using virtual environments. > > The first problem can be avoided because virtual environments can use a > different version of python than the system one. If you need an earlier > version of python then you can use it instead. I have multiple versions of Python on both Windows and Linux machines. I don't have to use the system version. On Windows the "py" launcher can launch any Python version on your system. > The second problem can be avoided because virtual environments exist in > a part of the file system that you have write access to, so you don't > need to use sudo to install packages. Your main user account does not > have write access to /usr/bin. And therefore on Linux pip will install packages as --user even if the option isn't specified. On Windows, one would just use --user routinely. > Also when a virtual environment is activated the path to it's packages > is a part of that environment so your code will always be able to import > the packages you want. Whenever a version of Python is launched its system path is set up so that its own packages are used. The one thing that can cause problems is programs in the Python Scripts directory, which may not be on the path for a particular version of Python. A virtual environment will take case of that, but I almost never run scripts in that directory so it's not an issue for me. I think there are situations where a venv is useful, but not because of the points you have asserted here. For myself, I find that after a while, I tend to forget what I set up the various venvs for, and what state they are in. So I have stopped using them. I just put up with having more packages in /site-packages than a particular applications needs. If I want to, say, work on code in a git clone's directory tree, I launch Python using a batch file that sets the PYTHONPATH to point there. > It's much easier to understand if you try it for yourself. Google has > many excellent resources, here is one > https://www.freecodecamp.org/news/how-to-setup-virtual-environments-in-python/ > > Best of luck :) > > R From cs at cskk.id.au Mon Sep 18 01:16:42 2023 From: cs at cskk.id.au (Cameron Simpson) Date: Mon, 18 Sep 2023 15:16:42 +1000 Subject: Why doc call `__init__` as a method rather than function? In-Reply-To: References: Message-ID: On 15Sep2023 10:49, scruel tao wrote: >```python >>>> class A: >... def __init__(self): >... pass >... >``` > >On many books and even the official documents, it seems that many authors prefer to call `__init__` as a "method" rather than a "function". >The book PYTHON CRASH COURSE mentioned that "A function that?s part of a class is a method.", however, ` A.__init__` tells that `__init__` is a function... As mentioned, methods in Python _are_ functions for use with a class. >>>> A.__init__ > >>>> a = A() >>>> a.__init__ > >> >I wonder how can I call `__init__` as? Consider the output above. >Maybe both are OK? As you can see, they're both legal expressions. The thing about `__init__` is that it's usually called automatically which you make a new object. Try putting a `print()` call in your `__init__` method, then make a new instance of `A`. The purpose of `__init__` is to initialise the object's attribute/state after the basic, empty-ish, object is made. Like other dunder methods (methods named with double underscores front and back) it is called automatically for you. In a subclass the `__init__` method calls the subperclass `__init__` and then does whatever additional things might be wanted by the subclass. Let's look at what you used above: >>> A.__init__ Here's we've just got a reference to the function you supposlied with the class definition for class `A`. This: >>> a = A() >>> a.__init__ Here's you've accessed the name `__init__` via an existing instance of `A`, your variable `a`. At this point you haven't called it. So you've got a callable thing which is a binding of the function to the object `a` i.e. when you call it, the "bound method" knows that t is associated with `a` and puts that in as the first argument (usually named `self`). Cheers, Cameron Simpson From c.buhtz at posteo.jp Mon Sep 18 01:52:58 2023 From: c.buhtz at posteo.jp (c.buhtz at posteo.jp) Date: Mon, 18 Sep 2023 05:52:58 +0000 Subject: PEP668 / pipx and "--editable" installs In-Reply-To: References: <988561df4bac884b3fe24b811b659946@posteo.de> <4RnhPQ0S6fz9rxM@submission02.posteo.de> Message-ID: <4Rpv8v52RVz9rxL@submission02.posteo.de> Thanks for your reply. btw: I do know what a virtual environment is and how its works. No need to explain. And again: I do expect "pipx" to use virtual environments. So this thread is not about pro and cons of using virtual environments. On 2023-09-17 11:57 Rimu Atkinson via Python-list wrote: > The first problem can be avoided because virtual environments can use > a different version of python than the system one. If you need an > earlier version of python then you can use it instead. But as I explained I used pipx to install it. So virtual environments are used in that case. Maybe I made not the problem clear enough: The problem is that the installed application ("hyperorg") did not see the system package "python3-dateutils". How can I solve this without(!) using another Python version? The behavior that the pipx-installed application is not able to see system python packages (installed via "apt install python3-dateutils") is unexpected to me. Maybe there is a good reason for that? Explain it please? Maybe I did something wrong? How can I make it right? Maybe it is a bug or a use case that is not covered by current version of pipx or Debian 12? > The second problem can be avoided because virtual environments exist > in a part of the file system Also here I assume I didn't make my problem clear enough. I tried to install a library (from source) with "pipx". But it did not work somehow (no clear error message). The global python interpreter did not see that library. Why? From roel at roelschroeven.net Mon Sep 18 04:14:20 2023 From: roel at roelschroeven.net (Roel Schroeven) Date: Mon, 18 Sep 2023 10:14:20 +0200 Subject: Confusing behavior of PYTHONWARNINGS In-Reply-To: References: Message-ID: <96a927b9-0e22-4e63-9487-e8356131604b@roelschroeven.net> Op 16/09/2023 om 10:17 schreef Meowxiik via Python-list: > Hello, > > For the third time I am trying to work with `PYTHONWARNINGS` filter, > and for the third time I am having a terrible time. I'd like to seek > your assistance, I have a few questions: > > **Question 1:** Does the environment variable only matter at python > interpreter startup time? If I set the same variable before python > start, it seems to work, but it doesn't work trough os.environ. It > does appear to be hinted at in the docs, but imho not clear enough. Yes, environment variables are only relevant when the interpreter starts up. The documentation (on the command line environment in general, not specific to PYTHONWARNINGS) says "These environment variables influence Python?s behavior, they are processed before the command-line switches other than -E or -I.". That implies they don't do anything if changed after startup. More specific to warnings, the documentation for the -W option (which is referenced in the PYTHONWARNINGS environment variable) says "Warnings can also be controlled using the PYTHONWARNINGS environment variable and from within a Python program using the warnings module." implying the same, and giving an alternative for controlling warnings from within Python. > **Question 2:** Why do the following filters not work for filtering > `urllib3.exceptions.InsecureRequestWarning` > > - `PYTHONWARNINGS=ignore:::urllib3.exceptions` > > - `PYTHONWARNINGS=ignore:::urllib3` > > - `PYTHONWARNINGS=ignore:::urllib3.exceptions` > > - `PYTHONWARNINGS=ignore::urllib3.exceptions.InsecureRequestWarning` > > None of these filter the warning. The last one has the audacity to > complain about "invalid module name: 'urllib3.exceptions'" which is > very confusing to me, given that that specific module is fully > importable during runtime, which I have tested. The only one I managed > to get working is `ignore:Unverified`, where "Unverified" is the first > word of the actual message, however I truly strongly dislike this > solution. I'd like to try this out myself, but I'm not familiar with urllib3 and I can't get to issue that warning; instead it throws exceptions (I tried a simple request with some of the URL's listed on https://badssl.com). How can I get urllib3 to issue that warning? Also, which version of Python are you using, and on which operating system? -- "Most of us, when all is said and done, like what we like and make up reasons for it afterwards." -- Soren F. Petersen From hjp-python at hjp.at Mon Sep 18 04:16:03 2023 From: hjp-python at hjp.at (Peter J. Holzer) Date: Mon, 18 Sep 2023 10:16:03 +0200 Subject: PEP668 / pipx and "--editable" installs In-Reply-To: <988561df4bac884b3fe24b811b659946@posteo.de> References: <988561df4bac884b3fe24b811b659946@posteo.de> Message-ID: <20230918081603.zhtx7jdptky65jai@hjp.at> On 2023-09-15 14:15:23 +0000, c.buhtz--- via Python-list wrote: > I tried to install it via "pipx install -e .[develop]". It's pyproject.toml > has a bug: A missing dependency "dateutil". But "dateutil" is not available > from PyPi for Python 3.11 (the default in Debian 12). But thanks to great > Debian they have a "python3-dateutil" package. I installed it. Sidenote: PyPI does have several packages with "dateutil" in their name. From the version number (2.8.2) I guess that "python-dateutil" is the one packaged in Debian 12. This can be installed via pip: % lsb_release -a No LSB modules are available. Distributor ID: Debian Description: Debian GNU/Linux 12 (bookworm) Release: 12 Codename: bookworm (dateutil) % pip install python-dateutil Collecting python-dateutil Downloading python_dateutil-2.8.2-py2.py3-none-any.whl (247 kB) ???????????????????????????????????????? 247.7/247.7 kB 3.1 MB/s eta 0:00:00 Collecting six>=1.5 Downloading six-1.16.0-py2.py3-none-any.whl (11 kB) Installing collected packages: six, python-dateutil Successfully installed python-dateutil-2.8.2 six-1.16.0 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 roel at roelschroeven.net Mon Sep 18 04:19:12 2023 From: roel at roelschroeven.net (Roel Schroeven) Date: Mon, 18 Sep 2023 10:19:12 +0200 Subject: Why doc call `__init__` as a method rather than function? In-Reply-To: <6a907429.54af.18a98f21d8d.Webtop.90@btinternet.com> References: <6a907429.54af.18a98f21d8d.Webtop.90@btinternet.com> Message-ID: Op 15/09/2023 om 15:05 schreef anthony.flury via Python-list: > Like all of the other ____ methods you shouldn't ever need to > call them directly : these are called dunder methods and represent > functions and features which are called by other operators. > > The only recommended way to call A.__init__ is to create an instance > of A : obj = A() - the __init__ method gets called automatically with > a newly created object. There is an exception: ? super().__init__() to call the base class's __init__ (normally from the derived class's __init__) -- "Human beings, who are almost unique in having the ability to learn from the experience of others, are also remarkable for their apparent disinclination to do so." -- Douglas Adams From scruelt at hotmail.com Mon Sep 18 06:43:20 2023 From: scruelt at hotmail.com (scruel tao) Date: Mon, 18 Sep 2023 10:43:20 +0000 Subject: Why doc call `__init__` as a method rather than function? In-Reply-To: References: <6a907429.54af.18a98f21d8d.Webtop.90@btinternet.com> Message-ID: Thanks for all repliers: @Tony & @Cameron, I do know related stuffs about the dunder methods, and your explanation just make it to be more clear, thank you! @Roel, you just caught everyone here, we do miss it even though we know it and use it regularly! @Clara > its both, depending on how you're getting it. Might can be more clear: its both, depending on how you're using/getting it. And I think I can mark this question as resolved, and with the following conclusions: As @Clara mentioned, we need to know that "all methods are functions", so we do can call `__init__` as a method or a function, or we can be avoid to have such discussion like Dan, and call it "the initializer" (However, you will need to think about ?what is this is? for other functions :). ). As @Alan mentioned, and according to the Wikipedia, in computer programming field, "method" is: > A method in object-oriented programming (OOP) is a procedure associated with an object, and generally also a message. An object consists of state data and behavior; these compose an interface, which specifies how the object may be used. A method is a behavior of an object parametrized by a user. For `__init__` and other functions in classes, we usually use them by writing code `obj.action()`, so we usually will call them as methods, so here, we call `action` or `__init__` as a method. However, if you use them by writing code `Clz.action(obj)`, then you'd better (or must?) to call them as functions, and it is not a "daily use case" in daily development, and in some languages, this behavior won't even be possible. **So, its kinda a "Majority rule" to call `__init__` (functions in classes) as a method.** === BTW, in Wikipedia, the "static methods" section is a very interesting: > Static methods are meant to be relevant to all the instances of a class rather than to any specific instance. This explanation might can "group" some functions back to "methods" :) However, let's still remember: All methods are functions, but not every function is a method. Thanks again for helping, you guys are really nice! From mats at wichmann.us Mon Sep 18 11:22:53 2023 From: mats at wichmann.us (Mats Wichmann) Date: Mon, 18 Sep 2023 09:22:53 -0600 Subject: PEP668 / pipx and "--editable" installs In-Reply-To: <20230918081603.zhtx7jdptky65jai@hjp.at> References: <988561df4bac884b3fe24b811b659946@posteo.de> <20230918081603.zhtx7jdptky65jai@hjp.at> Message-ID: <12f177b8-fd96-dd60-b0d4-6d25b79701d3@wichmann.us> On 9/18/23 02:16, Peter J. Holzer via Python-list wrote: > On 2023-09-15 14:15:23 +0000, c.buhtz--- via Python-list wrote: >> I tried to install it via "pipx install -e .[develop]". It's pyproject.toml >> has a bug: A missing dependency "dateutil". But "dateutil" is not available >> from PyPi for Python 3.11 (the default in Debian 12). But thanks to great >> Debian they have a "python3-dateutil" package. I installed it. > > Sidenote: > PyPI does have several packages with "dateutil" in their name. From the > version number (2.8.2) I guess that "python-dateutil" is the one > packaged in Debian 12. > > This can be installed via pip: It *is* the case that package name is not always equal to importable name. That certainly occurs in the universe of Python packages on PyPI; it's if anything much more likely on Linux distributions which have to share the package name namespace with a lot more than just Python packages (just for starters, what seems like billions of Perl packages), so you're even more likely to see names like python-foo or python3-foo when the thing you import is foo. That has nothing to do virtualenvs, of course. The use of a virtualenv for a project actually makes it more likely that you discover unstated dependencies, which is generally a good thing. From c.buhtz at posteo.jp Mon Sep 18 14:56:35 2023 From: c.buhtz at posteo.jp (c.buhtz at posteo.jp) Date: Mon, 18 Sep 2023 18:56:35 +0000 Subject: PEP668 / pipx and "--editable" installs In-Reply-To: <20230918081603.zhtx7jdptky65jai@hjp.at> References: <988561df4bac884b3fe24b811b659946@posteo.de> <20230918081603.zhtx7jdptky65jai@hjp.at> Message-ID: <4RqDY41p9kz6tw5@submission01.posteo.de> On 2023-09-18 10:16 "Peter J. Holzer via Python-list" wrote: > On 2023-09-15 14:15:23 +0000, c.buhtz--- via Python-list wrote: > > I tried to install it via "pipx install -e .[develop]". It's > > pyproject.toml has a bug: A missing dependency "dateutil". But > > "dateutil" is not available from PyPi for Python 3.11 (the default > > in Debian 12). But thanks to great Debian they have a > > "python3-dateutil" package. I installed it. > > This can be installed via pip: I'm aware of this. But this is not the question. I would like to know and understand why my via "pipx" installed package "hyperorg" is not able to see the systems packages installed via "apt install python3-dateutils"? Is this the usual behavior? Is this correct? What is the design decision behind it? Is it really the intention of PEP668 that pipx-installed packages are not allowed to use system packages? From mats at wichmann.us Mon Sep 18 15:09:38 2023 From: mats at wichmann.us (Mats Wichmann) Date: Mon, 18 Sep 2023 13:09:38 -0600 Subject: PEP668 / pipx and "--editable" installs In-Reply-To: <4RqDY41p9kz6tw5@submission01.posteo.de> References: <988561df4bac884b3fe24b811b659946@posteo.de> <20230918081603.zhtx7jdptky65jai@hjp.at> <4RqDY41p9kz6tw5@submission01.posteo.de> Message-ID: On 9/18/23 12:56, c.buhtz--- via Python-list wrote: > On 2023-09-18 10:16 "Peter J. Holzer via Python-list" > wrote: >> On 2023-09-15 14:15:23 +0000, c.buhtz--- via Python-list wrote: >>> I tried to install it via "pipx install -e .[develop]". It's >>> pyproject.toml has a bug: A missing dependency "dateutil". But >>> "dateutil" is not available from PyPi for Python 3.11 (the default >>> in Debian 12). But thanks to great Debian they have a >>> "python3-dateutil" package. I installed it. >> >> This can be installed via pip: > > I'm aware of this. But this is not the question. > > I would like to know and understand why my via "pipx" installed package > "hyperorg" is not able to see the systems packages installed via "apt > install python3-dateutils"? > > Is this the usual behavior? Is this correct? Yes. By default, the virtualenv contains just what you've installed. It's designed to give you tight control over what's installed, so you can track dependencies, avoid accidental inclusions, etc. As usual, you don't have to accept the default. For example, for the venv module: usage: venv [-h] [--system-site-packages] [--symlinks | --copies] [--clear] [--upgrade] [--without-pip] [--prompt PROMPT] [--upgrade-deps] ENV_DIR [ENV_DIR ...] Creates virtual Python environments in one or more target directories. positional arguments: ENV_DIR A directory to create the environment in. options: -h, --help show this help message and exit --system-site-packages Give the virtual environment access to the system site-packages dir. ... From list1 at tompassin.net Mon Sep 18 15:38:19 2023 From: list1 at tompassin.net (Thomas Passin) Date: Mon, 18 Sep 2023 15:38:19 -0400 Subject: PEP668 / pipx and "--editable" installs In-Reply-To: <4RqDY41p9kz6tw5@submission01.posteo.de> References: <988561df4bac884b3fe24b811b659946@posteo.de> <20230918081603.zhtx7jdptky65jai@hjp.at> <4RqDY41p9kz6tw5@submission01.posteo.de> Message-ID: On 9/18/2023 2:56 PM, c.buhtz--- via Python-list wrote: > On 2023-09-18 10:16 "Peter J. Holzer via Python-list" > wrote: >> On 2023-09-15 14:15:23 +0000, c.buhtz--- via Python-list wrote: >>> I tried to install it via "pipx install -e .[develop]". It's >>> pyproject.toml has a bug: A missing dependency "dateutil". But >>> "dateutil" is not available from PyPi for Python 3.11 (the default >>> in Debian 12). But thanks to great Debian they have a >>> "python3-dateutil" package. I installed it. >> >> This can be installed via pip: > > I'm aware of this. But this is not the question. > > I would like to know and understand why my via "pipx" installed package > "hyperorg" is not able to see the systems packages installed via "apt > install python3-dateutils"? > > Is this the usual behavior? Is this correct? > What is the design decision behind it? > > Is it really the intention of PEP668 that pipx-installed packages are > not allowed to use system packages? One way this could happen is if the hyperorg package got installed by a different version of Python than the system version. I've lost track of just how your installation is set up so this may not apply. But, for example, if the system is using Python 3.10.x and you installed hyperorg using Python 3.11, that would be such a situation. The apt-installed packages will get installed into the system python directories, rather than to the Python 3.11 directories. From PythonList at DancesWithMice.info Tue Sep 19 01:07:15 2023 From: PythonList at DancesWithMice.info (dn) Date: Tue, 19 Sep 2023 17:07:15 +1200 Subject: Python Launcher Pops Up When Py-based App Is Running (Mac) In-Reply-To: References: Message-ID: On 17/09/2023 13.20, James Greenham via Python-list wrote: > Hello, > > On the face of it, the Python-Mac mailing list is largely inactive so I'm posting here since it looks like this one is livelier. What happens when doGrab() is called from the REPL, after being 'fed' data you expect is valid? (per a unit-test) What code-level debugging has been exercised? Have you tried running the code in a debugger, in order to step into the (assumed) doGrab error? Sadly, this code is so old as to have grown whiskers. - are all the called-modules, eg webkit and the OpSys; still offering the appropriate interfaces, and continuing to behave in the expected fashion? (anything relevant in those Release Notes?) - in theory, Python 2 will still run. However, a reasonable proportion of today's Python-coders are unlikely to have ever used it. (Sunsetting Python 2 https://www.python.org/doc/sunset-python-2/) - were this code to be written using today's libraries, it is unlikely to look anything like this (which may also be contributing to the dearth of replies) -- Regards, =dn From thomas at python.org Tue Sep 19 07:30:21 2023 From: thomas at python.org (Thomas Wouters) Date: Tue, 19 Sep 2023 13:30:21 +0200 Subject: Python 3.12.0 rc3 (final release candidate I promise!) now available Message-ID: I'm pleased to announce the release of Python 3.12 release candidate 3. https://www.python.org/downloads/release/python-3120rc3/ This is the second release candidate of Python 3.12.0 This release, *3.12.0rc3*, is the absolutely last release preview for Python 3.12. There will be *no ABI changes* from this point forward in the 3.12 series. The intent is for the final release of 3.12.0, scheduled for Monday, 2023-10-02, to be identical to this release candidate. *This really is the last chance to find critical problems in Python 3.12.* Call to action We strongly encourage maintainers of third-party Python projects to prepare their projects for 3.12 compatibilities during this phase, and where necessary publish Python 3.12 wheels on PyPI to be ready for the final release of 3.12.0. Any binary wheels built against Python 3.12.0rc3 will work with future versions of Python 3.12. As always, report any issues to the Python bug tracker . Please keep in mind that this is a preview release and while it?s as close to the final release as we can get it, its use is *not* recommended for production environments. Core developers: time to work on documentation now - Are all your changes properly documented? - Are they mentioned in What?s New ? - Did you notice other changes you know of to have insufficient documentation? Major new features of the 3.12 series, compared to 3.11 New features - More flexible f-string parsing , allowing many things previously disallowed (PEP 701 ). - Support for the buffer protocol in Python code (PEP 688 ). - A new debugging/profiling API (PEP 669 ). - Support for isolated subinterpreters with separate Global Interpreter Locks (PEP 684 ). - Even more improved error messages . More exceptions potentially caused by typos now make suggestions to the user. - Support for the Linux perf profiler to report Python function names in traces. - Many large and small performance improvements (like PEP 709 and support for the BOLT binary optimizer), delivering an estimated 5% overall performance improvementcitation needed. Type annotations - New type annotation syntax for generic classes (PEP 695 ). - New override decorator for methods (PEP 698 ). Deprecations - 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 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 scheduled release of Python 3.12 will be 3.12.0, the *final release*, currently scheduled for 2023-10-02. More resources - Online Documentation . - PEP 693 , the Python 3.12 Release Schedule. - Report bugs via GitHub Issues . - Help fund Python and its community . We hope you enjoy the new releases! Thanks to all of the many volunteers who help make Python Development and these releases possible! Please consider supporting our efforts by volunteering yourself or through organization contributions to the Python Software Foundation . Your release team, Thomas Wouters Ned Deily Steve Dower ?ukasz Langa -- Thomas Wouters From hjp-python at hjp.at Wed Sep 20 08:43:41 2023 From: hjp-python at hjp.at (Peter J. Holzer) Date: Wed, 20 Sep 2023 14:43:41 +0200 Subject: PEP668 / pipx and "--editable" installs In-Reply-To: <4RqDY41p9kz6tw5@submission01.posteo.de> References: <988561df4bac884b3fe24b811b659946@posteo.de> <20230918081603.zhtx7jdptky65jai@hjp.at> <4RqDY41p9kz6tw5@submission01.posteo.de> Message-ID: <20230920124341.vu35waqphdcojp77@hjp.at> On 2023-09-18 18:56:35 +0000, c.buhtz--- via Python-list wrote: > On 2023-09-18 10:16 "Peter J. Holzer via Python-list" > wrote: > > On 2023-09-15 14:15:23 +0000, c.buhtz--- via Python-list wrote: > > > I tried to install it via "pipx install -e .[develop]". It's > > > pyproject.toml has a bug: A missing dependency "dateutil". But > > > "dateutil" is not available from PyPi for Python 3.11 (the default > > > in Debian 12). But thanks to great Debian they have a > > > "python3-dateutil" package. I installed it. > > > > This can be installed via pip: > > I'm aware of this. You wrote: > > > "dateutil" is not available from PyPi for Python 3.11 That's quite a curious thing to write if you are aware that dateutil is in fact available from PyPi for Python 3.11. > But this is not the question. I know. That's why I labeled my comment as a "Sidenote". 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 c.buhtz at posteo.jp Wed Sep 20 09:31:14 2023 From: c.buhtz at posteo.jp (c.buhtz at posteo.jp) Date: Wed, 20 Sep 2023 13:31:14 +0000 Subject: PEP668 / pipx and "--editable" installs In-Reply-To: <20230920124341.vu35waqphdcojp77@hjp.at> References: <988561df4bac884b3fe24b811b659946@posteo.de> <20230918081603.zhtx7jdptky65jai@hjp.at> <4RqDY41p9kz6tw5@submission01.posteo.de> <20230920124341.vu35waqphdcojp77@hjp.at> Message-ID: Dear Peter, maybe we have a missunderstanding. Am 20.09.2023 14:43 schrieb Peter J. Holzer via Python-list: >> > > "dateutil" is not available from PyPi for Python 3.11 > > That's quite a curious thing to write if you are aware that dateutil is > in fact available from PyPi for Python 3.11. Do I miss something here? See https://pypi.org/project/dateutils/ and also the open Issue about the missing support for Python 3.11 https://github.com/dateutil/dateutil/issues/1233 ? From hjp-python at hjp.at Wed Sep 20 12:13:53 2023 From: hjp-python at hjp.at (Peter J. Holzer) Date: Wed, 20 Sep 2023 18:13:53 +0200 Subject: dateutil on PyPI (was: PEP668 / pipx and "--editable" installs) In-Reply-To: References: <988561df4bac884b3fe24b811b659946@posteo.de> <20230918081603.zhtx7jdptky65jai@hjp.at> <4RqDY41p9kz6tw5@submission01.posteo.de> <20230920124341.vu35waqphdcojp77@hjp.at> Message-ID: <20230920161353.texgby4bnnl3gosu@hjp.at> On 2023-09-20 13:31:14 +0000, c.buhtz--- via Python-list wrote: > Dear Peter, > > maybe we have a missunderstanding. > > Am 20.09.2023 14:43 schrieb Peter J. Holzer via Python-list: > > > > > "dateutil" is not available from PyPi for Python 3.11 > > > > That's quite a curious thing to write if you are aware that dateutil is > > in fact available from PyPi for Python 3.11. > > Do I miss something here? > > See https://pypi.org/project/dateutils/ and also the open Issue about the > missing support for Python 3.11 You are missing at least an "s". "dateutils" is not "dateutil". But dateutils can also be installed from PyPI. > https://github.com/dateutil/dateutil/issues/1233 ? So it hasn't been tagged with any version >= 3.10 yet. That doesn't mean it isn't available. It requires a Python version >= 3.3, but 3.11 is >= 3.3, so that's not a problem. As I demonstrated, it installs just fine. 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 greg.ewing at canterbury.ac.nz Fri Sep 22 23:41:47 2023 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Sat, 23 Sep 2023 15:41:47 +1200 Subject: []=[] In-Reply-To: References: Message-ID: On 23/09/23 4:51 am, Stefan Ram wrote: > []=[] > > (Executes with no error.) ##### []=[] ( 1 ) #\_/# (Executes with no error.) -- Greg From jgossage at gmail.com Mon Sep 25 10:15:56 2023 From: jgossage at gmail.com (Jonathan Gossage) Date: Mon, 25 Sep 2023 10:15:56 -0400 Subject: Using generator expressions Message-ID: I am having a problem using generator expressions to supply the arguments for a class instance initialization. The following example shows the problem: class test1(object): def __init__(self, a, b): > self.name = a self.value = b st = 'Programming Renaissance, Any'.split(', ') y = test1(a for a in st) print(f'Object values are: {y._a}, {y._b}') I would expect to get the values from the list generated by splitting the string passed in as arguments to the new instance of test1, but instead I get the generator expression by itself as a generator object. The generator expression is treated like a passive object instead of being run. If I had wanted to pass the generator expression itself, I would have expected to have to use parentheses around the generator expression. Any suggestions on how to get the generator expression to run? If I change the definition of the input arguments to *args I can capture the arguments within __init__ but it is verbose and ugly. Also, I could accept the arguments from a Sequence and extract the Sequence members into the class values. I would prefer my solution if I could get it to work. Note that I tried generator expressions both inside parentheses and not, without success. -- Jonathan Gossage From dom.grigonis at gmail.com Mon Sep 25 10:23:52 2023 From: dom.grigonis at gmail.com (Dom Grigonis) Date: Mon, 25 Sep 2023 17:23:52 +0300 Subject: Using generator expressions In-Reply-To: References: Message-ID: <19E81B1D-A7FE-4B54-93A9-2F1DB6CEBBA1@gmail.com> y = test1(*[a for a in st]) y = test1(*st) Maybe any of these would be ok for you? Regards, DG > On 25 Sep 2023, at 17:15, Jonathan Gossage via Python-list wrote: > > I am having a problem using generator expressions to supply the arguments > for a class instance initialization. The following example shows the > problem: > > class test1(object): > def __init__(self, a, b): > >> self.name = a > > self.value = b > st = 'Programming Renaissance, Any'.split(', ') > y = test1(a for a in st) > print(f'Object values are: {y._a}, {y._b}') > > I would expect to get the values from the list generated by splitting the > string passed in as arguments to the new instance of test1, but instead > I get the generator expression by itself as a generator object. The > generator > expression is treated like a passive object instead of being run. If I had > wanted to pass the generator expression itself, I would have expected to > have > to use parentheses around the generator expression. Any suggestions on how > to > get the generator expression to run? > If I change the definition of the input arguments to *args I can capture the > arguments within __init__ but it is verbose and ugly. Also, I could accept > the > arguments from a Sequence and extract the Sequence members into the class > values. I would prefer my solution if I could get it to work. > Note that I tried generator expressions both inside parentheses and not, > without success. > > -- > Jonathan Gossage > -- > https://mail.python.org/mailman/listinfo/python-list From list1 at tompassin.net Mon Sep 25 11:08:26 2023 From: list1 at tompassin.net (Thomas Passin) Date: Mon, 25 Sep 2023 11:08:26 -0400 Subject: Using generator expressions In-Reply-To: References: Message-ID: On 9/25/2023 10:15 AM, Jonathan Gossage via Python-list wrote: > I am having a problem using generator expressions to supply the arguments > for a class instance initialization. The following example shows the > problem: > > class test1(object): > def __init__(self, a, b): > >> self.name = a > > self.value = b > st = 'Programming Renaissance, Any'.split(', ') > y = test1(a for a in st) > print(f'Object values are: {y._a}, {y._b}') > > I would expect to get the values from the list generated by splitting the > string passed in as arguments to the new instance of test1, but instead > I get the generator expression by itself as a generator object. The > generator > expression is treated like a passive object instead of being run. If I had > wanted to pass the generator expression itself, I would have expected to > have > to use parentheses around the generator expression. Any suggestions on how > to > get the generator expression to run? > If I change the definition of the input arguments to *args I can capture the > arguments within __init__ but it is verbose and ugly. Also, I could accept > the > arguments from a Sequence and extract the Sequence members into the class > values. I would prefer my solution if I could get it to work. > Note that I tried generator expressions both inside parentheses and not, > without success. > You should get an error at the y assignment. The argument of test1() is a generator, which would get assigned to the "a" argument, and there would be no "b" argument, which is an error. In any event, even if this were to work as you want, it would only work for strings that contain one comma. And you ask for values like y._a, but y._a is never created, only y.a. If you did convert the generator to a list, and if you fix the underscored variable names, it still wouldn't work because the arguments don't expect a list. Time to step back and figure out exactly what you actually want to do. From info at egenix.com Mon Sep 25 08:59:54 2023 From: info at egenix.com (eGenix Team) Date: Mon, 25 Sep 2023 14:59:54 +0200 Subject: =?UTF-8?Q?ANN=3A_Python_Meeting_D=C3=BCsseldorf_-_27=2E09=2E2023?= Message-ID: /This announcement is in German since it targets a local user group//meeting in D?sseldorf, Germany/ Ank?ndigung Python Meeting D?sseldorf - September 2023 Ein Treffen von Python Enthusiasten und Interessierten in ungezwungener Atmosph?re. *27.09.2023, 18:00 Uhr* Raum 1, 2.OG im B?rgerhaus Stadtteilzentrum Bilk D?sseldorfer Arcaden , Bachstr. 145, 40217 D?sseldorf Programm Bereits angemeldete Vortr?ge: * Moritz Damm: /Einf?hrung in '*Kedro - A framework for production-ready data science*' / * Marc-Andr? Lemburg: /Parsing structured content with *Python 3.10's new match-case */ * Arkadius Schuchhardt: /*Repository Pattern in Python*: Why and how? / * Jens Diemer: */CLI Tools/* Weitere Vortr?ge k?nnen gerne noch angemeldet werden. Bei Interesse, bitte unter info at pyddf.de melden. Startzeit und Ort Wir treffen uns um 18:00 Uhr im B?rgerhaus in den D?sseldorfer Arcaden. Das B?rgerhaus teilt sich den Eingang mit dem Schwimmbad und befindet sich an der Seite der Tiefgarageneinfahrt der D?sseldorfer Arcaden. ?ber dem Eingang steht ein gro?es "Schwimm? in Bilk" Logo. Hinter der T?r direkt links zu den zwei Aufz?gen, dann in den 2. Stock hochfahren. Der Eingang zum Raum 1 liegt direkt links, wenn man aus dem Aufzug kommt. >>> Eingang in Google Street View *?? Wichtig*: Bitte nur dann anmelden, wenn ihr absolut sicher seid, dass ihr auch kommt. Angesichts der begrenzten Anzahl Pl?tze, haben wir kein Verst?ndnis f?r kurzfristige Absagen oder No-Shows. Einleitung Das Python Meeting D?sseldorf ist eine regelm??ige Veranstaltung in D?sseldorf, die sich an Python Begeisterte aus der Region wendet. Einen guten ?berblick ?ber die Vortr?ge bietet unser PyDDF YouTube-Kanal , auf dem wir Videos der Vortr?ge nach den Meetings ver?ffentlichen. Veranstaltet wird das Meeting von der eGenix.com GmbH , Langenfeld, in Zusammenarbeit mit Clark Consulting & Research , D?sseldorf: Format Das Python Meeting D?sseldorf nutzt eine Mischung aus (Lightning) Talks und offener Diskussion. Vortr?ge k?nnen vorher angemeldet werden, oder auch spontan w?hrend des Treffens eingebracht werden. Ein Beamer mit HDMI und FullHD Aufl?sung steht zur Verf?gung. (Lightning) Talk Anmeldung bitte formlos per EMail an info at pyddf.de Kostenbeteiligung Das Python Meeting D?sseldorf wird von Python Nutzern f?r Python Nutzer veranstaltet. Da Tagungsraum, Beamer, Internet und Getr?nke Kosten produzieren, bitten wir die Teilnehmer um einen Beitrag in H?he von EUR 10,00 inkl. 19% Mwst. Sch?ler und Studenten zahlen EUR 5,00 inkl. 19% Mwst. Wir m?chten alle Teilnehmer bitten, den Betrag in bar mitzubringen. Anmeldung Da wir nur 25 Personen in dem angemieteten Raum empfangen k?nnen, m?chten wir bitten, sich vorher anzumelden. *Meeting Anmeldung* bitte per Meetup Weitere Informationen Weitere Informationen finden Sie auf der Webseite des Meetings: https://pyddf.de/ Viel Spa? ! -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Experts (#1, Sep 25 2023) >>> Python Projects, Coaching and Support ... https://www.egenix.com/ >>> Python Product Development ... https://consulting.egenix.com/ ________________________________________________________________________ ::: We implement business ideas - efficiently in both time and costs ::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611 https://www.egenix.com/company/contact/ https://www.malemburg.com/ From jgossage at gmail.com Mon Sep 25 11:37:16 2023 From: jgossage at gmail.com (Jonathan Gossage) Date: Mon, 25 Sep 2023 11:37:16 -0400 Subject: Using generator expressions In-Reply-To: References: Message-ID: Many thanks, all. It turned out that my problem was not fully understanding the use and power of the unpack operator *. Using it to activate my generator made things start to work. I changed the line where I invoked the generator to: y = test1(*(a for a in st)) adding the unpack operator. On Mon, Sep 25, 2023 at 11:15?AM Thomas Passin via Python-list < python-list at python.org> wrote: > On 9/25/2023 10:15 AM, Jonathan Gossage via Python-list wrote: > > I am having a problem using generator expressions to supply the arguments > > for a class instance initialization. The following example shows the > > problem: > > > > class test1(object): > > def __init__(self, a, b): > > > >> self.name = a > > > > self.value = b > > st = 'Programming Renaissance, Any'.split(', ') > > y = test1(a for a in st) > > print(f'Object values are: {y._a}, {y._b}') > > > > I would expect to get the values from the list generated by splitting the > > string passed in as arguments to the new instance of test1, but instead > > I get the generator expression by itself as a generator object. The > > generator > > expression is treated like a passive object instead of being run. If I > had > > wanted to pass the generator expression itself, I would have expected to > > have > > to use parentheses around the generator expression. Any suggestions on > how > > to > > get the generator expression to run? > > If I change the definition of the input arguments to *args I can capture > the > > arguments within __init__ but it is verbose and ugly. Also, I could > accept > > the > > arguments from a Sequence and extract the Sequence members into the class > > values. I would prefer my solution if I could get it to work. > > Note that I tried generator expressions both inside parentheses and not, > > without success. > > > > You should get an error at the y assignment. The argument of test1() is > a generator, which would get assigned to the "a" argument, and there > would be no "b" argument, which is an error. > > In any event, even if this were to work as you want, it would only work > for strings that contain one comma. And you ask for values like y._a, > but y._a is never created, only y.a. If you did convert the generator > to a list, and if you fix the underscored variable names, it still > wouldn't work because the arguments don't expect a list. > > Time to step back and figure out exactly what you actually want to do. > > -- > https://mail.python.org/mailman/listinfo/python-list > -- Jonathan Gossage From rosuav at gmail.com Mon Sep 25 11:42:27 2023 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 26 Sep 2023 01:42:27 +1000 Subject: Using generator expressions In-Reply-To: References: Message-ID: On Tue, 26 Sept 2023 at 01:39, Jonathan Gossage via Python-list wrote: > > Many thanks, all. It turned out that my problem was not fully understanding > the use and power of the unpack operator *. Using it to activate my > generator made things start to work. I changed the line where I invoked the > generator to: > y = test1(*(a for a in st)) > > adding the unpack operator. > You could simplify this with just the unpacking: y = test1(*st) ChrisA From piergiorgio.sartor.this.should.not.be.used at nexgo.REMOVETHIS.de Sat Sep 23 06:18:59 2023 From: piergiorgio.sartor.this.should.not.be.used at nexgo.REMOVETHIS.de (Piergiorgio Sartor) Date: Sat, 23 Sep 2023 12:18:59 +0200 Subject: []=[] In-Reply-To: References: Message-ID: On 23/09/2023 09.41, Stefan Ram wrote: > ram at zedat.fu-berlin.de (Stefan Ram) writes: >> []=[] > > I was watching a video of a David Beazley talk "Python > Concurrency From the Ground Up" , where he wrote > > can_recv, can_send, [] = select(recv_wait, send_wait, []) > > . Later, he clarified that he actually wanted to write > > can_recv, can_send, _ = select(recv_wait, send_wait, []) > > and that he was surprised how the "[]" gave no error. > ("I wonder why that works.") If you try: [] = [1] and check the error, it will be clear how it works. Maybe not why... :-) bye, -- piergiorgio From rosuav at gmail.com Mon Sep 25 12:56:39 2023 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 26 Sep 2023 02:56:39 +1000 Subject: []=[] In-Reply-To: References: Message-ID: On Tue, 26 Sept 2023 at 02:52, Piergiorgio Sartor via Python-list wrote: > > On 23/09/2023 09.41, Stefan Ram wrote: > > ram at zedat.fu-berlin.de (Stefan Ram) writes: > >> []=[] > > > > I was watching a video of a David Beazley talk "Python > > Concurrency From the Ground Up" , where he wrote > > > > can_recv, can_send, [] = select(recv_wait, send_wait, []) > > > > . Later, he clarified that he actually wanted to write > > > > can_recv, can_send, _ = select(recv_wait, send_wait, []) > > > > and that he was surprised how the "[]" gave no error. > > ("I wonder why that works.") > > If you try: > > [] = [1] > > and check the error, it will be clear how it works. > Maybe not why... :-) > Note that the reason it gives no error is that select() returned an empty iterable as the third value. And you can be sure that it will ALWAYS return an empty iterable, because select() returns three values that correspond to the three parameters, and are subsets of them - that is to say, everything in can_recv must have previously been in recv_wait, and everything in can_send must have been in send_wait. Since the third (waiting for exceptional conditions) was empty, there can't ever be anything to return, and so [] will work, and unpack zero elements. ChrisA From rob.cliffe at btinternet.com Sun Sep 24 18:42:18 2023 From: rob.cliffe at btinternet.com (Rob Cliffe) Date: Sun, 24 Sep 2023 23:42:18 +0100 Subject: []=[] In-Reply-To: References: Message-ID: <626fee7f-1ae9-7be3-2675-427604be3239@btinternet.com> It's not a bug, it's an empty unpacking. Just as you can write ??? [A,B] = [1,2] # Sets A to 1, B to 2 Best wishes Rob Cliffe On 23/09/2023 04:41, Greg Ewing via Python-list wrote: > On 23/09/23 4:51 am, Stefan Ram wrote: >> []=[] >> >> ?? (Executes with no error.) > > ##### > []=[] > ( 1 ) > #\_/# > > (Executes with no error.) > From pau.vilchez.uso at gmail.com Mon Sep 25 14:10:09 2023 From: pau.vilchez.uso at gmail.com (Pau Vilchez) Date: Mon, 25 Sep 2023 14:10:09 -0400 Subject: Unable to uninstall 3.10.9 Message-ID: Hello Python Team, I am somehow unable to completely remove Python 3.10.9 (64 Bit) from my computer. I have tried deleting the Appdata folder then repairing and then uninstalling but it still persists in the remove/add program function in windows 10. I am just trying to reinstall it because I didn?t add it to the path correctly, any help is greatly appreciated. Very Respectfully, Pau Vilchez From peter at thoughtmachine.net Tue Sep 26 09:20:58 2023 From: peter at thoughtmachine.net (Peter Ebden) Date: Tue, 26 Sep 2023 14:20:58 +0100 Subject: The GIL and PyEval_RestoreThread Message-ID: Hi all, I've been working on embedding Python and have an interesting case around locking with PyEval_RestoreThread which wasn't quite doing what I expect, hoping someone can explain what I should expect here. I have a little example (I'm running this in parallel from two different threads; I have some more C code for that but I don't think it's super interesting): void run_python(PyThreadState* thread) { LOG("Restoring thread %p...", thread); PyEval_RestoreThread(thread); LOG("Restored thread %p", thread); PyRun_SimpleString("import time; print('sleeping'); time.sleep(3.0)"); LOG("Saving thread..."); PyThreadState* saved_thread = PyEval_SaveThread(); LOG("Saved thread %p", saved_thread); } This produces output like 11:46:48.110058893: Restoring thread 0xabc480... 11:46:48.110121656: Restored thread 0xabc480 11:46:48.110166060: Restoring thread 0xabc480... sleeping 11:46:48.110464194: Restored thread 0xabc480 sleeping 11:46:51.111307541: Saving thread... 11:46:51.111361075: Saved thread 0xabc480 11:46:51.113116633: Saving thread... 11:46:51.113177605: Saved thread 0xabc480 The thing that surprises me is that both threads seem to be able to pass PyEval_RestoreThread before either reaches the corresponding PyEval_SaveThread call, which I wasn't expecting to happen; I assumed that since RestoreThread acquires the GIL, that thread state would remain locked until it's released. I understand that the system occasionally switches threads, which I guess might well happen with that time.sleep() call, but I wasn't expecting the same thread to become usable somewhere else. Maybe I am just confusing things by approaching the same Python thread from multiple OS threads concurrently and should be managing my own locking around that? Thanks in advance, Peter -- Thought Machine Group Limited, a company registered in England & Wales. Registered number: 11114277.? Registered Office:?5 New Street Square, London EC4A 3TW . The content of this email is confidential and intended for the recipient specified in message only. It is strictly forbidden to share any part of this message with any third party, without a written consent of the sender. If you received this message by mistake, please reply to this message and follow with its deletion, so that we can ensure such a mistake does not occur in the future. From nbthdehuvkfiyfyj at gmail.com Tue Sep 26 08:27:24 2023 From: nbthdehuvkfiyfyj at gmail.com (Abdelkhelk ashref salay eabakh) Date: Tue, 26 Sep 2023 05:27:24 -0700 (PDT) Subject: error of opening Python Message-ID: <339d2a79-4799-46e8-96cb-2f1f63688fd7n@googlegroups.com> Dear Python team, This is my not first time using Python, I tried to launch Python and it showed "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." I don't know what this meant and how to fix this. Could you please help me? Thank you very much. Kind regards From michael.stemper at gmail.com Tue Sep 26 09:20:40 2023 From: michael.stemper at gmail.com (Michael F. Stemper) Date: Tue, 26 Sep 2023 08:20:40 -0500 Subject: error of opening Python In-Reply-To: <339d2a79-4799-46e8-96cb-2f1f63688fd7n@googlegroups.com> References: <339d2a79-4799-46e8-96cb-2f1f63688fd7n@googlegroups.com> Message-ID: On 26/09/2023 07.27, Abdelkhelk ashref salay eabakh wrote: > Dear Python team, > > This is my not first time using Python, I tried to launch Python and it showed > "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." I > don't know what this meant and how to fix this. Could you please help me? What error did you encounter? Aside from the lack of line breaks, it looks quite similar to what I get when I start up python: Python 3.6.9 (default, Mar 10 2023, 16:46:00) [GCC 8.4.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> Didn't you get the ">>> " prompt? Once you get it, it shows that the Read, Evaluate, Print Loop (REPL) is ready for you to type some python statements. For instance: >>> x = 2**3 >>> print(x) 8 >>> -- Michael F. Stemper Outside of a dog, a book is man's best friend. Inside of a dog, it's too dark to read. From chris_roysmith at internode.on.net Tue Sep 26 22:30:54 2023 From: chris_roysmith at internode.on.net (Chris Roy-Smith) Date: Wed, 27 Sep 2023 12:30:54 +1000 Subject: error of opening Python In-Reply-To: <339d2a79-4799-46e8-96cb-2f1f63688fd7n@googlegroups.com> References: <339d2a79-4799-46e8-96cb-2f1f63688fd7n@googlegroups.com> Message-ID: On 26/9/23 22:27, Abdelkhelk ashref salay eabakh via Python-list wrote: > Dear Python team, > > This is my not first time using Python, I tried to launch Python and it showed I'm no expert but.... > "Python 3.11.3 (tags/v3.11.3:f3909b8, Apr 4 2023, 23:49:59) [MSC v.1934 64 bit (AMD64)] on win surely running a 64 bit version of python in a 23mbit version of windows will cause significant problems! try the correct python or windows regards, > Type "help", "copyright", "credits" or "license" for more information." I > don't know what this meant and how to fix this. Could you please help me? > Thank you very much. > > Kind regards From python at mrabarnett.plus.com Tue Sep 26 22:48:15 2023 From: python at mrabarnett.plus.com (MRAB) Date: Wed, 27 Sep 2023 03:48:15 +0100 Subject: The GIL and PyEval_RestoreThread In-Reply-To: References: Message-ID: <620973cc-7e7f-7f30-3f34-56cb05c5084b@mrabarnett.plus.com> On 2023-09-26 14:20, Peter Ebden via Python-list wrote: > Hi all, > > I've been working on embedding Python and have an interesting case around > locking with PyEval_RestoreThread which wasn't quite doing what I expect, > hoping someone can explain what I should expect here. > > I have a little example (I'm running this in parallel from two different > threads; I have some more C code for that but I don't think it's super > interesting): > > void run_python(PyThreadState* thread) { > LOG("Restoring thread %p...", thread); > PyEval_RestoreThread(thread); > LOG("Restored thread %p", thread); > PyRun_SimpleString("import time; print('sleeping'); time.sleep(3.0)"); > LOG("Saving thread..."); > PyThreadState* saved_thread = PyEval_SaveThread(); > LOG("Saved thread %p", saved_thread); > } > > This produces output like > 11:46:48.110058893: Restoring thread 0xabc480... > 11:46:48.110121656: Restored thread 0xabc480 > 11:46:48.110166060: Restoring thread 0xabc480... > sleeping > 11:46:48.110464194: Restored thread 0xabc480 > sleeping > 11:46:51.111307541: Saving thread... > 11:46:51.111361075: Saved thread 0xabc480 > 11:46:51.113116633: Saving thread... > 11:46:51.113177605: Saved thread 0xabc480 > > The thing that surprises me is that both threads seem to be able to pass > PyEval_RestoreThread before either reaches the corresponding > PyEval_SaveThread call, which I wasn't expecting to happen; I assumed that > since RestoreThread acquires the GIL, that thread state would remain locked > until it's released. > > I understand that the system occasionally switches threads, which I guess > might well happen with that time.sleep() call, but I wasn't expecting the > same thread to become usable somewhere else. Maybe I am just confusing > things by approaching the same Python thread from multiple OS threads > concurrently and should be managing my own locking around that? > Storing the result of PyEval_SaveThread in a local variable looks wrong to me. In the source for the regex module, I release the GIL with PyEval_SaveThread and save its result. Then, when I want to claim the GIL, I pass that saved value to PyEval_RestoreThread. You seem to be releasing the GIL and discarding the result, so which thread are you resuming when you call PyEval_RestoreThread? It looks like you're resuming the same thread twice. As it's already resumed the second time, no wonder it's not blocking! From python at mrabarnett.plus.com Tue Sep 26 22:55:42 2023 From: python at mrabarnett.plus.com (MRAB) Date: Wed, 27 Sep 2023 03:55:42 +0100 Subject: error of opening Python In-Reply-To: References: <339d2a79-4799-46e8-96cb-2f1f63688fd7n@googlegroups.com> Message-ID: <45a9b2dc-33e3-efe1-12d9-23165a0ed15c@mrabarnett.plus.com> On 2023-09-27 03:30, Chris Roy-Smith via Python-list wrote: > On 26/9/23 22:27, Abdelkhelk ashref salay eabakh via Python-list wrote: >> Dear Python team, >> >> This is my not first time using Python, I tried to launch Python and it showed > > I'm no expert but.... >> "Python 3.11.3 (tags/v3.11.3:f3909b8, Apr 4 2023, 23:49:59) [MSC v.1934 64 bit (AMD64)] on win > surely running a 64 bit version of python in a 23mbit version of windows > will cause significant problems! > It says "win32" even on 64-bit Windows. If you try to run 64-bit Python on 32-bit Windows, it won't get as far as printing that header! > try the correct python or windows > > regards, > > > >> Type "help", "copyright", "credits" or "license" for more information." I >> don't know what this meant and how to fix this. Could you please help me? >> Thank you very much. >> >> Kind regards > > > From greg.ewing at canterbury.ac.nz Wed Sep 27 02:36:47 2023 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Wed, 27 Sep 2023 19:36:47 +1300 Subject: error of opening Python In-Reply-To: References: <339d2a79-4799-46e8-96cb-2f1f63688fd7n@googlegroups.com> Message-ID: On 27/09/23 3:30 pm, Chris Roy-Smith wrote: > surely running a 64 bit version of python in a 23mbit version of windows > will cause significant problems! 23 millibits? I don't think you'd be able to run much at all with that few bits! :-) -- Greg From peter at thoughtmachine.net Wed Sep 27 05:14:45 2023 From: peter at thoughtmachine.net (Peter Ebden) Date: Wed, 27 Sep 2023 10:14:45 +0100 Subject: The GIL and PyEval_RestoreThread In-Reply-To: <620973cc-7e7f-7f30-3f34-56cb05c5084b@mrabarnett.plus.com> References: <620973cc-7e7f-7f30-3f34-56cb05c5084b@mrabarnett.plus.com> Message-ID: The thread variable I'm passing in is the one I originally got from calling Py_NewInterpreter. I'd assumed that I didn't need to particularly track the one I get back from SaveThread since it should always be the one I restored previously (which does seem to be the case). > It looks like you're resuming the same thread twice. As it's already resumed the second time, no wonder it's not blocking! That isn't how I read the docs though? It says "If the lock has been created, the current thread must not have acquired it, otherwise deadlock ensues." That suggests to me that it should try to acquire the GIL again and wait until it can (although possibly also that it's not an expected use and Python thread states are expected to be more 1:1 with C threads). On Wed, Sep 27, 2023 at 3:53?AM MRAB via Python-list wrote: > On 2023-09-26 14:20, Peter Ebden via Python-list wrote: > > Hi all, > > > > I've been working on embedding Python and have an interesting case around > > locking with PyEval_RestoreThread which wasn't quite doing what I expect, > > hoping someone can explain what I should expect here. > > > > I have a little example (I'm running this in parallel from two different > > threads; I have some more C code for that but I don't think it's super > > interesting): > > > > void run_python(PyThreadState* thread) { > > LOG("Restoring thread %p...", thread); > > PyEval_RestoreThread(thread); > > LOG("Restored thread %p", thread); > > PyRun_SimpleString("import time; print('sleeping'); time.sleep(3.0)"); > > LOG("Saving thread..."); > > PyThreadState* saved_thread = PyEval_SaveThread(); > > LOG("Saved thread %p", saved_thread); > > } > > > > This produces output like > > 11:46:48.110058893: Restoring thread 0xabc480... > > 11:46:48.110121656: Restored thread 0xabc480 > > 11:46:48.110166060: Restoring thread 0xabc480... > > sleeping > > 11:46:48.110464194: Restored thread 0xabc480 > > sleeping > > 11:46:51.111307541: Saving thread... > > 11:46:51.111361075: Saved thread 0xabc480 > > 11:46:51.113116633: Saving thread... > > 11:46:51.113177605: Saved thread 0xabc480 > > > > The thing that surprises me is that both threads seem to be able to pass > > PyEval_RestoreThread before either reaches the corresponding > > PyEval_SaveThread call, which I wasn't expecting to happen; I assumed > that > > since RestoreThread acquires the GIL, that thread state would remain > locked > > until it's released. > > > > I understand that the system occasionally switches threads, which I guess > > might well happen with that time.sleep() call, but I wasn't expecting the > > same thread to become usable somewhere else. Maybe I am just confusing > > things by approaching the same Python thread from multiple OS threads > > concurrently and should be managing my own locking around that? > > > Storing the result of PyEval_SaveThread in a local variable looks wrong > to me. > > In the source for the regex module, I release the GIL with > PyEval_SaveThread and save its result. Then, when I want to claim the > GIL, I pass that saved value to PyEval_RestoreThread. > > You seem to be releasing the GIL and discarding the result, so which > thread are you resuming when you call PyEval_RestoreThread? > > It looks like you're resuming the same thread twice. As it's already > resumed the second time, no wonder it's not blocking! > > -- > https://mail.python.org/mailman/listinfo/python-list > -- Thought Machine Group Limited, a company registered in England & Wales. Registered number: 11114277.? Registered Office:?5 New Street Square, London EC4A 3TW . The content of this email is confidential and intended for the recipient specified in message only. It is strictly forbidden to share any part of this message with any third party, without a written consent of the sender. If you received this message by mistake, please reply to this message and follow with its deletion, so that we can ensure such a mistake does not occur in the future. From robin at reportlab.com Wed Sep 27 07:47:36 2023 From: robin at reportlab.com (Robin Becker) Date: Wed, 27 Sep 2023 12:47:36 +0100 Subject: venv --upgrade 3.12.0rc2 --> 3.12.0rc3 failure Message-ID: <8dd58351-45d9-42e7-a6d4-30b72b0e470d@reportlab.com> Attempting venv upgrade 3.12.0rc2 --> 3.12.0rc3 I find pyvenv.cfg changes, but the virtual python doesn't. I guess this ought to be a bug. > user at host:~/devel > $ ~/LOCAL?3.12.0rc2/bin/python3 -m venv xxx > bash: /home/user/LOCAL?3.12.0rc2/bin/python3: No such file or directory > user at host:~/devel > $ ~/LOCAL/3.12.0rc2/bin/python3 -m venv xxx > user at host:~/devel > $ xxx/bin/python -c'import sys;print(sys.version)' > 3.12.0rc2 (main, Sep 9 2023, 17:53:34) [GCC 13.2.1 20230801] > user at host:~/devel > $ cat xxx/pyvenv.cfg > home = /home/user/LOCAL/3.12.0rc2/bin > include-system-site-packages = false > version = 3.12.0 > executable = /home/user/LOCAL/3.12.0rc2/bin/python3.12 > command = /home/user/LOCAL/3.12.0rc2/bin/python3 -m venv /home/robin/devel/xxx > user at host:~/devel > $ ~/LOCAL/3.12.0rc3/bin/python3 -m venv --upgrade xxx > user at host:~/devel > $ xxx/bin/python -c'import sys;print(sys.version)' > 3.12.0rc2 (main, Sep 9 2023, 17:53:34) [GCC 13.2.1 20230801] > user at host:~/devel > $ cat xxx/pyvenv.cfg > home = /home/user/LOCAL/3.12.0rc3/bin > include-system-site-packages = false > version = 3.12.0 > executable = /home/user/LOCAL/3.12.0rc3/bin/python3.12 > command = /home/user/LOCAL/3.12.0rc3/bin/python3 -m venv --upgrade /home/robin/devel/xxx > user at host:~/devel > $ # check versions > user at host:~/devel > $ ~/LOCAL/3.12.0rc2/bin/python3 -c'import sys;print(sys.version)' > 3.12.0rc2 (main, Sep 9 2023, 17:53:34) [GCC 13.2.1 20230801] > user at host:~/devel > $ ~/LOCAL/3.12.0rc3/bin/python3 -c'import sys;print(sys.version)' > 3.12.0rc3 (main, Sep 27 2023, 09:35:10) [GCC 13.2.1 20230801] > user at host:~/devel > $ -- Robin Becker From mats at wichmann.us Wed Sep 27 10:19:49 2023 From: mats at wichmann.us (Mats Wichmann) Date: Wed, 27 Sep 2023 08:19:49 -0600 Subject: Unable to uninstall 3.10.9 In-Reply-To: References: Message-ID: <4ae9ccd4-f01b-1c89-8520-8ba3a56dffef@wichmann.us> On 9/25/23 12:10, Pau Vilchez via Python-list wrote: > Hello Python Team, > > > > I am somehow unable to completely remove Python 3.10.9 (64 Bit) from my > computer. I have tried deleting the Appdata folder then repairing and then > uninstalling but it still persists in the remove/add program function in > windows 10. I am just trying to reinstall it because I didn?t add it to the > path correctly, any help is greatly appreciated. Rerunning the installer and telling it uninstall should normally work (if you can't get to that from the Programs applet, then you can start from the installer itself). You can also fix the path addition from the Modify screen in the installer, you don't need to uninstall for that. If it's really stuck, the Windows installer subsystem could have gotten confused, usually this tool works for folks: https://support.microsoft.com/en-us/topic/fix-problems-that-block-programs-from-being-installed-or-removed-cca7d1b6-65a9-3d98-426b-e9f927e1eb4d From kuchipudizurishaddai8 at gmail.com Wed Sep 27 07:17:06 2023 From: kuchipudizurishaddai8 at gmail.com (Zuri Shaddai Kuchipudi) Date: Wed, 27 Sep 2023 04:17:06 -0700 (PDT) Subject: upgrade of pip on my python 2.7 version Message-ID: <34359189-43ad-4110-abbc-ad8310a75353n@googlegroups.com> hello everyone this the error that im getting while trying to install and upgrade pip on what is the solution for it? C:\repository\pst-utils-pc-davinci-simulator>pip install You are using pip version 7.0.1, however version 23.2.1 is available. You should consider upgrading via the 'pip install --upgrade pip' command. You must give at least one requirement to install (see "pip help install") C:\repository\pst-utils-pc-davinci-simulator>pip install --upgrade pip You are using pip version 7.0.1, however version 23.2.1 is available. You should consider upgrading via the 'pip install --upgrade pip' command. Collecting pip Using cached https://files.pythonhosted.org/packages/ba/19/e63fb4e0d20e48bd2167bb7e857abc0e21679e24805ba921a224df8977c0/pip-23.2.1.tar.gz Complete output from command python setup.py egg_info: Traceback (most recent call last): File "", line 20, in File "c:\users\kuchipz\appdata\local\temp\pip-build-gc4ekm\pip\setup.py", line 7 def read(rel_path: str) -> str: ^ SyntaxError: invalid syntax ---------------------------------------- Command "python setup.py egg_info" failed with error code 1 in c:\users\kuchipz\appdata\local\temp\pip-build-gc4ekm\pip From list1 at tompassin.net Wed Sep 27 12:49:09 2023 From: list1 at tompassin.net (Thomas Passin) Date: Wed, 27 Sep 2023 12:49:09 -0400 Subject: upgrade of pip on my python 2.7 version In-Reply-To: <34359189-43ad-4110-abbc-ad8310a75353n@googlegroups.com> References: <34359189-43ad-4110-abbc-ad8310a75353n@googlegroups.com> Message-ID: <02bf4aef-8519-aea3-0eea-097c6a5b967b@tompassin.net> On 9/27/2023 7:17 AM, Zuri Shaddai Kuchipudi via Python-list wrote: > hello everyone this the error that im getting while trying to install and upgrade pip on what is the solution for it? > > C:\repository\pst-utils-pc-davinci-simulator>pip install > You are using pip version 7.0.1, however version 23.2.1 is available. > You should consider upgrading via the 'pip install --upgrade pip' command. > You must give at least one requirement to install (see "pip help install") > > C:\repository\pst-utils-pc-davinci-simulator>pip install --upgrade pip > You are using pip version 7.0.1, however version 23.2.1 is available. > You should consider upgrading via the 'pip install --upgrade pip' command. > Collecting pip > Using cached https://files.pythonhosted.org/packages/ba/19/e63fb4e0d20e48bd2167bb7e857abc0e21679e24805ba921a224df8977c0/pip-23.2.1.tar.gz > Complete output from command python setup.py egg_info: > Traceback (most recent call last): > File "", line 20, in > File "c:\users\kuchipz\appdata\local\temp\pip-build-gc4ekm\pip\setup.py", line 7 > def read(rel_path: str) -> str: > ^ > SyntaxError: invalid syntax > > ---------------------------------------- > Command "python setup.py egg_info" failed with error code 1 in c:\users\kuchipz\appdata\local\temp\pip-build-gc4ekm\pip Possibly this: https://techglimpse.com/install-higher-version-pip-python27/ From rosuav at gmail.com Wed Sep 27 14:11:16 2023 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 28 Sep 2023 04:11:16 +1000 Subject: upgrade of pip on my python 2.7 version In-Reply-To: <34359189-43ad-4110-abbc-ad8310a75353n@googlegroups.com> References: <34359189-43ad-4110-abbc-ad8310a75353n@googlegroups.com> Message-ID: On Thu, 28 Sept 2023 at 01:16, Zuri Shaddai Kuchipudi via Python-list wrote: > > hello everyone this the error that im getting while trying to install and upgrade pip on what is the solution for it? > The solution is to upgrade to Python 3. https://pip.pypa.io/en/latest/development/release-process/#python-2-support ChrisA From larry.martell at gmail.com Wed Sep 27 14:53:57 2023 From: larry.martell at gmail.com (Larry Martell) Date: Wed, 27 Sep 2023 11:53:57 -0700 Subject: path to python in venv Message-ID: I was under the impression that in a venv the python used would be in the venv's bin dir. But in my venvs I see this in the bin dirs: lrwxrwxrwx 1 larrymartell larrymartell 7 Sep 27 11:21 python -> python3 lrwxrwxrwx 1 larrymartell larrymartell 16 Sep 27 11:21 python3 -> /usr/bin/python3 Googling this I read: The presence of symbolic links like python and python3 in the bin directory of your virtual environment pointing to the system Python executable (/usr/bin/python) suggests that the virtual environment was created using the system Python interpreter rather than a standalone Python installation. This can happen if you create a virtual environment using a system-wide Python interpreter, and the virtual environment inherits some of the symbolic links or shortcuts from the system Python installation. In this case, your virtual environment is not fully isolated because it still relies on the system Python interpreter. Not sure what this really means, nor how to get python to be in my venv. From mats at wichmann.us Wed Sep 27 15:32:19 2023 From: mats at wichmann.us (Mats Wichmann) Date: Wed, 27 Sep 2023 13:32:19 -0600 Subject: upgrade of pip on my python 2.7 version In-Reply-To: <34359189-43ad-4110-abbc-ad8310a75353n@googlegroups.com> References: <34359189-43ad-4110-abbc-ad8310a75353n@googlegroups.com> Message-ID: <595d0250-7c64-866e-bf53-44c5e433d153@wichmann.us> On 9/27/23 05:17, Zuri Shaddai Kuchipudi via Python-list wrote: > hello everyone this the error that im getting while trying to install and upgrade pip on what is the solution for it? > > C:\repository\pst-utils-pc-davinci-simulator>pip install > You are using pip version 7.0.1, however version 23.2.1 is available. > You should consider upgrading via the 'pip install --upgrade pip' command. > You must give at least one requirement to install (see "pip help install") > > C:\repository\pst-utils-pc-davinci-simulator>pip install --upgrade pip > You are using pip version 7.0.1, however version 23.2.1 is available. > You should consider upgrading via the 'pip install --upgrade pip' command. > Collecting pip > Using cached https://files.pythonhosted.org/packages/ba/19/e63fb4e0d20e48bd2167bb7e857abc0e21679e24805ba921a224df8977c0/pip-23.2.1.tar.gz > Complete output from command python setup.py egg_info: > Traceback (most recent call last): > File "", line 20, in > File "c:\users\kuchipz\appdata\local\temp\pip-build-gc4ekm\pip\setup.py", line 7 > def read(rel_path: str) -> str: > ^ > SyntaxError: invalid syntax PyPI *should* be returning a compatible version of pip to upgrade to. pip itself has long since dropped support for 2.7, and the version you're trying to force is pretty clear: pip 23.2.1 Meta License: MIT License (MIT) Author: The pip developers Requires: Python >=3.7 ... Classifiers Development Status 5 - Production/Stable Intended Audience Developers License OSI Approved :: MIT License Programming Language Python Python :: 3 Python :: 3 :: Only ... So "don't do that". Why it's trying to select an incompatible version when you ask to upgrade is not something I'd like to speculate on, for me personally that's a surprise. Maybe something else you did before? Also make sure you're using a pip that matches your Python. It's usually safer if you invoke it as: python -m pip install --upgrade pip (or whatever the precise name of your Python 2 interpreter actually is) From jon+usenet at unequivocal.eu Wed Sep 27 14:56:39 2023 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Wed, 27 Sep 2023 18:56:39 -0000 (UTC) Subject: path to python in venv References: Message-ID: On 2023-09-27, Larry Martell wrote: > I was under the impression that in a venv the python used would be in > the venv's bin dir. But in my venvs I see this in the bin dirs: > > lrwxrwxrwx 1 larrymartell larrymartell 7 Sep 27 11:21 python -> python3 > lrwxrwxrwx 1 larrymartell larrymartell 16 Sep 27 11:21 python3 -> > /usr/bin/python3 ... > Not sure what this really means, nor how to get python to be in my venv. WHy do you want python to be "in your venv"? From larry.martell at gmail.com Wed Sep 27 15:46:06 2023 From: larry.martell at gmail.com (Larry Martell) Date: Wed, 27 Sep 2023 12:46:06 -0700 Subject: path to python in venv In-Reply-To: References: Message-ID: On Wed, Sep 27, 2023 at 12:42?PM Jon Ribbens via Python-list wrote: > > On 2023-09-27, Larry Martell wrote: > > I was under the impression that in a venv the python used would be in > > the venv's bin dir. But in my venvs I see this in the bin dirs: > > > > lrwxrwxrwx 1 larrymartell larrymartell 7 Sep 27 11:21 python -> python3 > > lrwxrwxrwx 1 larrymartell larrymartell 16 Sep 27 11:21 python3 -> > > /usr/bin/python3 > ... > > Not sure what this really means, nor how to get python to be in my venv. > > WHy do you want python to be "in your venv"? Isn't that the entire point of a venv? To have a completely self contained env? So if someone messes with the system python it will not break code running in the venv. From niktarlirik at zohomail.com Wed Sep 27 15:52:59 2023 From: niktarlirik at zohomail.com (Niktar Lirik) Date: Wed, 27 Sep 2023 22:52:59 +0300 Subject: path to python in venv In-Reply-To: References: Message-ID: <18ad833a3e3.4b7c7069535736904.1341861085186326507@zoho.com> Hi Larry, You could just create venv with option '?copies' For example: python -m venv -?copies .venv From: Larry Martell via Python-list Sent: 27 ???????? 2023 ?. 22:48 To: Jon Ribbens Cc: python-list at python.org Subject: Re: path to python in venv On Wed, Sep 27, 2023 at 12:42?PM Jon Ribbens via Python-list wrote: > > On 2023-09-27, Larry Martell wrote: > > I was under the impression that in a venv the python used would be in > > the venv's bin dir. But in my venvs I see this in the bin dirs: > > > > lrwxrwxrwx 1 larrymartell larrymartell 7 Sep 27 11:21 python -> python3 > > lrwxrwxrwx 1 larrymartell larrymartell 16 Sep 27 11:21 python3 -> > > /usr/bin/python3 > ... > > Not sure what this really means, nor how to get python to be in my venv. > > WHy do you want python to be "in your venv"? Isn't that the entire point of a venv? To have a completely self contained env? So if someone messes with the system python it will not break code running in the venv. -- https://mail.python.org/mailman/listinfo/python-list From larry.martell at gmail.com Wed Sep 27 16:01:46 2023 From: larry.martell at gmail.com (Larry Martell) Date: Wed, 27 Sep 2023 13:01:46 -0700 Subject: path to python in venv In-Reply-To: <18ad833a3e3.4b7c7069535736904.1341861085186326507@zoho.com> References: <18ad833a3e3.4b7c7069535736904.1341861085186326507@zoho.com> Message-ID: On Wed, Sep 27, 2023 at 12:53?PM Niktar Lirik wrote: > > Hi Larry, > > You could just create venv with option '?copies' > > > > For example: > > python -m venv -?copies .venv Thanks! That is just what I was looking for. > From: Larry Martell via Python-list > Sent: 27 ???????? 2023 ?. 22:48 > To: Jon Ribbens > Cc: python-list at python.org > Subject: Re: path to python in venv > > > > On Wed, Sep 27, 2023 at 12:42?PM Jon Ribbens via Python-list > > wrote: > > > > > > On 2023-09-27, Larry Martell wrote: > > > > I was under the impression that in a venv the python used would be in > > > > the venv's bin dir. But in my venvs I see this in the bin dirs: > > > > > > > > lrwxrwxrwx 1 larrymartell larrymartell 7 Sep 27 11:21 python -> python3 > > > > lrwxrwxrwx 1 larrymartell larrymartell 16 Sep 27 11:21 python3 -> > > > > /usr/bin/python3 > > > ... > > > > Not sure what this really means, nor how to get python to be in my venv. > > > > > > WHy do you want python to be "in your venv"? > > > > Isn't that the entire point of a venv? To have a completely self > > contained env? So if someone messes with the system python it will not > > break code running in the venv. > > -- > > https://mail.python.org/mailman/listinfo/python-list > > From mats at wichmann.us Wed Sep 27 16:09:41 2023 From: mats at wichmann.us (Mats Wichmann) Date: Wed, 27 Sep 2023 14:09:41 -0600 Subject: path to python in venv In-Reply-To: References: Message-ID: On 9/27/23 13:46, Larry Martell via Python-list wrote: > On Wed, Sep 27, 2023 at 12:42?PM Jon Ribbens via Python-list > wrote: >> >> On 2023-09-27, Larry Martell wrote: >>> I was under the impression that in a venv the python used would be in >>> the venv's bin dir. But in my venvs I see this in the bin dirs: >>> >>> lrwxrwxrwx 1 larrymartell larrymartell 7 Sep 27 11:21 python -> python3 >>> lrwxrwxrwx 1 larrymartell larrymartell 16 Sep 27 11:21 python3 -> >>> /usr/bin/python3 >> ... >>> Not sure what this really means, nor how to get python to be in my venv. >> >> WHy do you want python to be "in your venv"? > > Isn't that the entire point of a venv? To have a completely self > contained env? So if someone messes with the system python it will not > break code running in the venv. It can do that, it just turns out the defaults are to not make a dedicated Python instance, and to not give access to the system site packages. The venv and virtualenv modules, at least, will let you override either of those defaults via command-line options at creation time. Once a year I have virtualenvs break when the new Python version appears in Fedora, which is irritating, but I take the attitude that virtualenvs are disposable and (try to) not let it bother me that I forgot to deal with that ahead of time. It helps if you make sure that a virtualenv has a record of its dependencies - perhaps a requirements.txt file in the project it's being used to build, so it's easy to recreate them. From kuchipudizurishaddai8 at gmail.com Wed Sep 27 16:02:31 2023 From: kuchipudizurishaddai8 at gmail.com (Zuri Shaddai Kuchipudi) Date: Wed, 27 Sep 2023 13:02:31 -0700 (PDT) Subject: upgrade of pip on my python 2.7 version In-Reply-To: References: <595d0250-7c64-866e-bf53-44c5e433d153@wichmann.us> <34359189-43ad-4110-abbc-ad8310a75353n@googlegroups.com> Message-ID: On Wednesday, 27 September 2023 at 21:32:53 UTC+2, Mats Wichmann wrote: > On 9/27/23 05:17, Zuri Shaddai Kuchipudi via Python-list wrote: > > hello everyone this the error that im getting while trying to install and upgrade pip on what is the solution for it? > > > > C:\repository\pst-utils-pc-davinci-simulator>pip install > > You are using pip version 7.0.1, however version 23.2.1 is available. > > You should consider upgrading via the 'pip install --upgrade pip' command. > > You must give at least one requirement to install (see "pip help install") > > > > C:\repository\pst-utils-pc-davinci-simulator>pip install --upgrade pip > > You are using pip version 7.0.1, however version 23.2.1 is available. > > You should consider upgrading via the 'pip install --upgrade pip' command. > > Collecting pip > > Using cached https://files.pythonhosted.org/packages/ba/19/e63fb4e0d20e48bd2167bb7e857abc0e21679e24805ba921a224df8977c0/pip-23.2.1.tar.gz > > Complete output from command python setup.py egg_info: > > Traceback (most recent call last): > > File "", line 20, in > > File "c:\users\kuchipz\appdata\local\temp\pip-build-gc4ekm\pip\setup.py", line 7 > > def read(rel_path: str) -> str: > > ^ > > SyntaxError: invalid syntax > PyPI *should* be returning a compatible version of pip to upgrade to. > pip itself has long since dropped support for 2.7, and the version > you're trying to force is pretty clear: > > pip 23.2.1 > > Meta > License: MIT License (MIT) > Author: The pip developers > Requires: Python >=3.7 > ... > Classifiers > Development Status > 5 - Production/Stable > Intended Audience > Developers > License > OSI Approved :: MIT License > Programming Language > Python > Python :: 3 > Python :: 3 :: Only > ... > > So "don't do that". > > Why it's trying to select an incompatible version when you ask to > upgrade is not something I'd like to speculate on, for me personally > that's a surprise. Maybe something else you did before? > > Also make sure you're using a pip that matches your Python. It's usually > safer if you invoke it as: > > python -m pip install --upgrade pip > > (or whatever the precise name of your Python 2 interpreter actually is) the code that i want to run and all the libraries are written for python 2 but i have seen a video where the person showed the 2to3 pip method in which it rewrites the code in python 3 and shows all the necessary changes. From jon+usenet at unequivocal.eu Wed Sep 27 16:32:25 2023 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Wed, 27 Sep 2023 20:32:25 -0000 (UTC) Subject: path to python in venv References: Message-ID: On 2023-09-27, Larry Martell wrote: > On Wed, Sep 27, 2023 at 12:42?PM Jon Ribbens via Python-list > wrote: >> On 2023-09-27, Larry Martell wrote: >> > I was under the impression that in a venv the python used would be in >> > the venv's bin dir. But in my venvs I see this in the bin dirs: >> > >> > lrwxrwxrwx 1 larrymartell larrymartell 7 Sep 27 11:21 python -> python3 >> > lrwxrwxrwx 1 larrymartell larrymartell 16 Sep 27 11:21 python3 -> >> > /usr/bin/python3 >> ... >> > Not sure what this really means, nor how to get python to be in my venv. >> >> WHy do you want python to be "in your venv"? > > Isn't that the entire point of a venv? To have a completely self > contained env? So if someone messes with the system python it will not > break code running in the venv. The main point of the venv is to isolate the installed packages, rather than Python itself. I'm a bit surprised your symlinks are as shown above though - mine link from python to python3.11 to /usr/bin/python3.11, so it wouldn't change the version of python used even if I installed a different system python version. From mats at wichmann.us Wed Sep 27 17:26:14 2023 From: mats at wichmann.us (Mats Wichmann) Date: Wed, 27 Sep 2023 15:26:14 -0600 Subject: upgrade of pip on my python 2.7 version In-Reply-To: References: <595d0250-7c64-866e-bf53-44c5e433d153@wichmann.us> <34359189-43ad-4110-abbc-ad8310a75353n@googlegroups.com> Message-ID: On 9/27/23 14:02, Zuri Shaddai Kuchipudi via Python-list wrote: >> Why it's trying to select an incompatible version when you ask to >> upgrade is not something I'd like to speculate on, for me personally >> that's a surprise. Maybe something else you did before? >> >> Also make sure you're using a pip that matches your Python. It's usually >> safer if you invoke it as: >> >> python -m pip install --upgrade pip >> >> (or whatever the precise name of your Python 2 interpreter actually is) > the code that i want to run and all the libraries are written for python 2 but i have seen a video where the person showed the 2to3 pip method in which it rewrites the code in python 3 and shows all the necessary changes. Upgrading to Python 3 is the best answer... except when it isn't. If you want to convert a small project it's usually not too hard; and using a conversion tool can work well. If you have libraries "not under your control" expect a lot more work. You can upgrade pip to the latest available version for Python 2.7 - will take some research, I don't know what that version might be. Or you could try this: https://bootstrap.pypa.io/pip/2.7/get-pip.py If you were using a Linux distro, you probably don't want to mess with the "system pip" which is usually set up to understand details of how that distro's Python is packaged. It looks like you're on Windows by the paths in your original message, so that should be okay. Or... you could just ignore the message suggesting you upgrade pip, and proceed, hoping things will stay working as they are. From rosuav at gmail.com Wed Sep 27 17:32:26 2023 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 28 Sep 2023 07:32:26 +1000 Subject: upgrade of pip on my python 2.7 version In-Reply-To: References: <595d0250-7c64-866e-bf53-44c5e433d153@wichmann.us> <34359189-43ad-4110-abbc-ad8310a75353n@googlegroups.com> Message-ID: On Thu, 28 Sept 2023 at 07:27, Mats Wichmann via Python-list wrote: > > Upgrading to Python 3 is the best answer... except when it isn't. If > you want to convert a small project it's usually not too hard; and using > a conversion tool can work well. Just remember that Python 2.7.18, the very last version of Python 2, was released in 2020 and has not changed since. There are not even security patches being released (at least, not from python.org - but if you're using a different distribution of Python, you are also quite possibly using their package manager rather than pip). Staying on a version of Python that hasn't had new features since 2010 and hasn't had bug fixes since 2020 is going to become increasingly problematic. Convert your code. Pay the price in development time now and then reap the benefits, rather than paying the price when you run into a massive issue somewhere down the track and there's no options left to you. Convert while you still have the luxury of running the old code. ChrisA From PythonList at DancesWithMice.info Wed Sep 27 18:42:36 2023 From: PythonList at DancesWithMice.info (dn) Date: Thu, 28 Sep 2023 11:42:36 +1300 Subject: path to python in venv In-Reply-To: References: Message-ID: On 28/09/2023 09.32, Jon Ribbens via Python-list wrote: > On 2023-09-27, Larry Martell wrote: >> On Wed, Sep 27, 2023 at 12:42?PM Jon Ribbens via Python-list >> wrote: >>> On 2023-09-27, Larry Martell wrote: >>>> I was under the impression that in a venv the python used would be in >>>> the venv's bin dir. But in my venvs I see this in the bin dirs: >>>> >>>> lrwxrwxrwx 1 larrymartell larrymartell 7 Sep 27 11:21 python -> python3 >>>> lrwxrwxrwx 1 larrymartell larrymartell 16 Sep 27 11:21 python3 -> >>>> /usr/bin/python3 >>> ... >>>> Not sure what this really means, nor how to get python to be in my venv. >>> >>> WHy do you want python to be "in your venv"? >> >> Isn't that the entire point of a venv? To have a completely self >> contained env? So if someone messes with the system python it will not >> break code running in the venv. > > The main point of the venv is to isolate the installed packages, > rather than Python itself. I'm a bit surprised your symlinks are > as shown above though - mine link from python to python3.11 to > /usr/bin/python3.11, so it wouldn't change the version of python > used even if I installed a different system python version. "venv ? Creation of virtual environments" (https://docs.python.org/3/library/venv.html) starts by saying: ?The venv module supports creating lightweight ?virtual environments?, each with their own independent set of Python packages installed in their site directories.? but later expands this with: ?Used to contain a specific Python interpreter...? even though the primary use-case treats the system interpreter as the "base" Python/environment. Time for some reading and proving appropriate combinations of options? Over the years there have been various proposals to enable multiple versions of Python to exist concurrently on a single machine, notably Python2 + Python3 - but am failing to recall any official docs on Python3.n + Python3.m; eg "PEP 554 ? Multiple Interpreters in the Stdlib" (https://peps.python.org/pep-0554/). That said there's plenty of articles on-line (which may/not feature venv*) such as "Multiple Python interpreters" (https://developer.fedoraproject.org/tech/languages/python/multiple-pythons.html) * although the OP didn't mention an OpSys, one poster did mention Fedora-Linux... NB some of this info may be dated - it is some time since conducted this investigation (and decided not to use venv - apologies!) Am currently using PyCharm (courtesy of recent teams' conventions) and it eases both problems (which interpreter, and which development-environment/activation steps) but in automating 'the boring stuff' it will be interesting to see if in-future, I notice when the project is based upon an older system! FYI https://www.jetbrains.com/help/pycharm/installing-uninstalling-and-reloading-interpreter-paths.html (I'd be surprised if the other major tool-sets don't offer something similar) Disclaimer: JetBrains sponsor our local PUG-meetings with a door-prize. -- -- Regards, =dn From hjp-python at hjp.at Wed Sep 27 18:51:45 2023 From: hjp-python at hjp.at (Peter J. Holzer) Date: Thu, 28 Sep 2023 00:51:45 +0200 Subject: path to python in venv In-Reply-To: References: Message-ID: <20230927225145.fq7x57fithelvx4k@hjp.at> On 2023-09-27 20:32:25 -0000, Jon Ribbens via Python-list wrote: > On 2023-09-27, Larry Martell wrote: > > On Wed, Sep 27, 2023 at 12:42?PM Jon Ribbens via Python-list wrote: > >> On 2023-09-27, Larry Martell wrote: > >> > lrwxrwxrwx 1 larrymartell larrymartell 7 Sep 27 11:21 python -> python3 > >> > lrwxrwxrwx 1 larrymartell larrymartell 16 Sep 27 11:21 python3 -> /usr/bin/python3 [...] > I'm a bit surprised your symlinks are as shown above though - mine > link from python to python3.11 to /usr/bin/python3.11, so it wouldn't > change the version of python used even if I installed a different > system python version. That's probably because you created the venvs with "python3.11 -m venv ...". The symlink points to the command you used to create it: % python3 -m venv venv % ll venv/bin/python* lrwxrwxrwx 1 hjp hjp 7 Aug 29 2022 venv/bin/python -> python3* lrwxrwxrwx 1 hjp hjp 12 Aug 29 2022 venv/bin/python3 -> /bin/python3* lrwxrwxrwx 1 hjp hjp 7 Aug 29 2022 venv/bin/python3.10 -> python3* % python3.10 -m venv venv % ll venv/bin/python* lrwxrwxrwx 1 hjp hjp 10 Sep 28 00:45 venv/bin/python -> python3.10* lrwxrwxrwx 1 hjp hjp 10 Sep 28 00:45 venv/bin/python3 -> python3.10* lrwxrwxrwx 1 hjp hjp 15 Sep 28 00:45 venv/bin/python3.10 -> /bin/python3.10* 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 list1 at tompassin.net Wed Sep 27 20:28:17 2023 From: list1 at tompassin.net (Thomas Passin) Date: Wed, 27 Sep 2023 20:28:17 -0400 Subject: path to python in venv In-Reply-To: References: Message-ID: On 9/27/2023 2:53 PM, Larry Martell via Python-list wrote: > I was under the impression that in a venv the python used would be in > the venv's bin dir. But in my venvs I see this in the bin dirs: > > lrwxrwxrwx 1 larrymartell larrymartell 7 Sep 27 11:21 python -> python3 > lrwxrwxrwx 1 larrymartell larrymartell 16 Sep 27 11:21 python3 -> > /usr/bin/python3 > > Googling this I read: > > The presence of symbolic links like python and python3 in the bin > directory of your virtual environment pointing to the system Python > executable (/usr/bin/python) suggests that the virtual environment was > created using the system Python interpreter rather than a standalone > Python installation. > > This can happen if you create a virtual environment using a > system-wide Python interpreter, and the virtual environment inherits > some of the symbolic links or shortcuts from the system Python > installation. In this case, your virtual environment is not fully > isolated because it still relies on the system Python interpreter. > > Not sure what this really means, nor how to get python to be in my venv. You don't need to "get python to be in my venv". The venv contains its own Python Lib directory, and whatever site-packages installs you want for that venv. In essence, the script for launching the venv sets up the PYTHONPATH variable and some other paths so that Python finds its files in the venv directories instead of in the usual Python locations. Setting these paths may involve creating symbolic links and that is all done for you. The thing you need to appreciate is that when you create a venv with a command like this: -m venv path/to/venv this will all link back to whatever version of Python you used in place of . If you invoked it with python3, on Linux you will get whatever your system runs when you type "python3", which would usually be the system's Python install. If you want to use some other version of Python, say python3.10, then just run that one instead when you create the venv. From barry at barrys-emacs.org Thu Sep 28 05:05:00 2023 From: barry at barrys-emacs.org (Barry) Date: Thu, 28 Sep 2023 10:05:00 +0100 Subject: venv --upgrade 3.12.0rc2 --> 3.12.0rc3 failure In-Reply-To: <8dd58351-45d9-42e7-a6d4-30b72b0e470d@reportlab.com> References: <8dd58351-45d9-42e7-a6d4-30b72b0e470d@reportlab.com> Message-ID: <5A8810A8-F004-4486-90ED-9580BF3B1C82@barrys-emacs.org> > On 27 Sep 2023, at 12:50, Robin Becker via Python-list wrote: > > Attempting venv upgrade 3.12.0rc2 --> 3.12.0rc3 I find pyvenv.cfg changes, but the virtual python doesn't. > I guess this ought to be a bug. You must delete and then recreate the venv if the version of python changes. It is not a bug in python. Barry From robin at reportlab.com Thu Sep 28 06:40:14 2023 From: robin at reportlab.com (Robin Becker) Date: Thu, 28 Sep 2023 11:40:14 +0100 Subject: venv --upgrade 3.12.0rc2 --> 3.12.0rc3 failure In-Reply-To: <5A8810A8-F004-4486-90ED-9580BF3B1C82@barrys-emacs.org> References: <8dd58351-45d9-42e7-a6d4-30b72b0e470d@reportlab.com> <5A8810A8-F004-4486-90ED-9580BF3B1C82@barrys-emacs.org> Message-ID: On 28/09/2023 10:05, Barry via Python-list wrote: So this must be the source of my confusion user at host:~ $ python312 -mvenv --help ...... --upgrade Upgrade the environment directory to use this version of Python, assuming Python has been upgraded in-place. ...... I have a different version, but it's not 'in place'. thanks -- Robin > > >> On 27 Sep 2023, at 12:50, Robin Becker via Python-list wrote: >> >> Attempting venv upgrade 3.12.0rc2 --> 3.12.0rc3 I find pyvenv.cfg changes, but the virtual python doesn't. >> I guess this ought to be a bug. > > You must delete and then recreate the venv if the version of python changes. > It is not a bug in python. > > Barry > > From loris.bennett at fu-berlin.de Thu Sep 28 03:31:31 2023 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Thu, 28 Sep 2023 09:31:31 +0200 Subject: Installing package as root to a system directory Message-ID: <87msx6lpnw.fsf@zedat.fu-berlin.de> Hi, I use poetry to develop system software packages as a normal user. To install the packages I use, again as a normal user export PYTHONUSERBASE=/some/path pip3 install --user somepackage.whl and add /some/path to /usr/lib64/python3.6/site-packages/zedat.pth This works well enough, but seems to me to be a little clunky, mainly because the files don't then belong to root. The most correct way, in my case, would probably be to create an RPM out of the Python package, but that seems like it would be too much overhead. What other approaches to people use? Cheers, Loris -- This signature is currently under constuction. From kuchipudizurishaddai8 at gmail.com Thu Sep 28 09:23:27 2023 From: kuchipudizurishaddai8 at gmail.com (Zuri Shaddai Kuchipudi) Date: Thu, 28 Sep 2023 06:23:27 -0700 (PDT) Subject: upgrade of pip on my python 2.7 version In-Reply-To: References: <595d0250-7c64-866e-bf53-44c5e433d153@wichmann.us> <34359189-43ad-4110-abbc-ad8310a75353n@googlegroups.com> Message-ID: <7777d6c8-08a0-4342-8297-bba95c316a8fn@googlegroups.com> On Wednesday, 27 September 2023 at 23:33:02 UTC+2, Chris Angelico wrote: > On Thu, 28 Sept 2023 at 07:27, Mats Wichmann via Python-list > wrote: > > > > Upgrading to Python 3 is the best answer... except when it isn't. If > > you want to convert a small project it's usually not too hard; and using > > a conversion tool can work well. > Just remember that Python 2.7.18, the very last version of Python 2, > was released in 2020 and has not changed since. There are not even > security patches being released (at least, not from python.org - but > if you're using a different distribution of Python, you are also quite > possibly using their package manager rather than pip). Staying on a > version of Python that hasn't had new features since 2010 and hasn't > had bug fixes since 2020 is going to become increasingly problematic. > > Convert your code. Pay the price in development time now and then reap > the benefits, rather than paying the price when you run into a massive > issue somewhere down the track and there's no options left to you. > > Convert while you still have the luxury of running the old code. > > ChrisA but how do i convert it chris just downloading the python version 3 will solve my issue? and what about the changes From list1 at tompassin.net Thu Sep 28 11:43:25 2023 From: list1 at tompassin.net (Thomas Passin) Date: Thu, 28 Sep 2023 11:43:25 -0400 Subject: upgrade of pip on my python 2.7 version In-Reply-To: <7777d6c8-08a0-4342-8297-bba95c316a8fn@googlegroups.com> References: <595d0250-7c64-866e-bf53-44c5e433d153@wichmann.us> <34359189-43ad-4110-abbc-ad8310a75353n@googlegroups.com> <7777d6c8-08a0-4342-8297-bba95c316a8fn@googlegroups.com> Message-ID: On 9/28/2023 9:23 AM, Zuri Shaddai Kuchipudi via Python-list wrote: > On Wednesday, 27 September 2023 at 23:33:02 UTC+2, Chris Angelico wrote: >> On Thu, 28 Sept 2023 at 07:27, Mats Wichmann via Python-list >> wrote: >>> >>> Upgrading to Python 3 is the best answer... except when it isn't. If >>> you want to convert a small project it's usually not too hard; and using >>> a conversion tool can work well. >> Just remember that Python 2.7.18, the very last version of Python 2, >> was released in 2020 and has not changed since. There are not even >> security patches being released (at least, not from python.org - but >> if you're using a different distribution of Python, you are also quite >> possibly using their package manager rather than pip). Staying on a >> version of Python that hasn't had new features since 2010 and hasn't >> had bug fixes since 2020 is going to become increasingly problematic. >> >> Convert your code. Pay the price in development time now and then reap >> the benefits, rather than paying the price when you run into a massive >> issue somewhere down the track and there's no options left to you. >> >> Convert while you still have the luxury of running the old code. >> >> ChrisA > but how do i convert it chris just downloading the python version 3 will solve my issue? and what about the changes You have to modify your existing Python code. It's often easy to do. There is the tool that tries to convert from Python 2 to Python 3; you may need to do some extra work after that. Depending on the code you may even be able to make it work with both Python 2.7 and 3.x. Often the biggest change is to print statements: Python 2: print a, b, c Python3: print(a, b, c) If you are very unlucky, your code will depend on some package that has never been ported to Python 3. But that would be unusual. From anthony.flury at btinternet.com Wed Sep 27 03:29:35 2023 From: anthony.flury at btinternet.com (anthony.flury) Date: Wed, 27 Sep 2023 08:29:35 +0100 (BST) Subject: error of opening Python In-Reply-To: <339d2a79-4799-46e8-96cb-2f1f63688fd7n@googlegroups.com> References: <339d2a79-4799-46e8-96cb-2f1f63688fd7n@googlegroups.com> Message-ID: <5fed2f2f.a934.18ad58b1123.Webtop.93@btinternet.com> This isn't an error. This is just a normal Python Header message announcing that you are using Python 3.11.3 The rest is just information from the build system : The build Id, the date/time the build was made, and the version of the compiler. There is nothing to fix. ------ Original Message ------ From: "Abdelkhelk ashref salay eabakh via Python-list" To: python-list at python.org Sent: Tuesday, 26 Sep, 23 At 13:27 Subject: error of opening Python Dear Python team, This is my not first time using Python, I tried to launch Python and it showed "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." I don't know what this meant and how to fix this. Could you please help me? Thank you very much. Kind regards -- https://mail.python.org/mailman/listinfo/python-list --
Anthony Flury
anthony.flury at btinternet.com From greg.ewing at canterbury.ac.nz Fri Sep 29 23:54:21 2023 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Sat, 30 Sep 2023 16:54:21 +1300 Subject: Dynamically modifying "__setattr__" In-Reply-To: References: Message-ID: On 28/09/23 10:44 pm, Stefan Ram wrote: > class A: > def __init__( self ): > self.__setattr__ = self.setattr > def setattr( self, key, value ): > print( 'setattr called.' ) > > Any idea how to achieve something like this? class A: def __init__(self): self.x = 17 self.setattr = self.custom_setattr def __setattr__(self, key, value): self.setattr(key, value) def setattr(self, key, value): object.__setattr__(self, key, value) def custom_setattr(self, key, value): print('custom_setattr:', key, '=', value) a = A() a.x = 1 print('a.x =', a.x) -- Greg From Karsten.Hilbert at gmx.net Sat Sep 30 15:00:40 2023 From: Karsten.Hilbert at gmx.net (Karsten Hilbert) Date: Sat, 30 Sep 2023 21:00:40 +0200 Subject: type annotation vs working code Message-ID: A type annotation isn't supposed to change what code does, or so I thought: #------------------------------------------------------------ class Borg: _instances:dict = {} def __new__(cls, *args, **kargs): # look up subclass instance cache if Borg._instances.get(cls) is None: Borg._instances[cls] = object.__new__(cls) return Borg._instances[cls] class WorkingSingleton(Borg): def __init__(self): print(self.__class__.__name__, ':') try: self.already_initialized print('already initialized') return except AttributeError: print('initializing') self.already_initialized = True self.special_value = 42 class FailingSingleton(Borg): def __init__(self): print(self.__class__.__name__, ':') try: self.already_initialized:bool print('already initialized') return except AttributeError: print('initializing') self.already_initialized = True self.special_value = 42 s = WorkingSingleton() print(s.special_value) s = FailingSingleton() print(s.special_value) #------------------------------------------------------------ Notice how Working* and Failing differ in the type annotation of self.already_initialized only. Output: WorkingSingleton : initializing 42 FailingSingleton : already initialized <====================== Huh ? Traceback (most recent call last): File "/home/ncq/Projekte/gm/git/gnumed/gnumed/client/testing/test-singleton.py", line 48, in print(s.special_value) ^^^^^^^^^^^^^^^ AttributeError: 'FailingSingleton' object has no attribute 'special_value' Where's the error in my thinking (or code) ? Thanks, Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B From mats at wichmann.us Sat Sep 30 15:34:52 2023 From: mats at wichmann.us (Mats Wichmann) Date: Sat, 30 Sep 2023 13:34:52 -0600 Subject: type annotation vs working code In-Reply-To: References: Message-ID: On 9/30/23 13:00, Karsten Hilbert via Python-list wrote: > A type annotation isn't supposed to change what code does, > or so I thought: > > #------------------------------------------------------------ > class Borg: > _instances:dict = {} > > def __new__(cls, *args, **kargs): > # look up subclass instance cache > if Borg._instances.get(cls) is None: > Borg._instances[cls] = object.__new__(cls) > return Borg._instances[cls] > > > class WorkingSingleton(Borg): > > def __init__(self): > print(self.__class__.__name__, ':') > try: > self.already_initialized > print('already initialized') > return > > except AttributeError: > print('initializing') > > self.already_initialized = True > self.special_value = 42 > > > class FailingSingleton(Borg): > > def __init__(self): > print(self.__class__.__name__, ':') > try: > self.already_initialized:bool > print('already initialized') > return > > except AttributeError: > print('initializing') > > self.already_initialized = True > self.special_value = 42 > > s = WorkingSingleton() > print(s.special_value) > > s = FailingSingleton() > print(s.special_value) > > #------------------------------------------------------------ > > Notice how Working* and Failing differ in the type annotation > of self.already_initialized only. What happens here is in the second case, the line is just recorded as a variable annotation, and is not evaluated as a reference, as you're expecting to happen, so it just goes right to the print call without raising the exception. You could change your initializer like this: def __init__(self): print(self.__class__.__name__, ':') self.already_initialized: bool try: self.already_initialized print('already initialized') return The syntax description is here: https://peps.python.org/pep-0526/#global-and-local-variable-annotations From PythonList at DancesWithMice.info Sat Sep 30 16:04:05 2023 From: PythonList at DancesWithMice.info (dn) Date: Sun, 1 Oct 2023 09:04:05 +1300 Subject: type annotation vs working code In-Reply-To: References: Message-ID: On 01/10/2023 08.00, Karsten Hilbert via Python-list wrote: > A type annotation isn't supposed to change what code does, > or so I thought: > > #------------------------------------------------------------ > class Borg: > _instances:dict = {} > > def __new__(cls, *args, **kargs): > # look up subclass instance cache > if Borg._instances.get(cls) is None: > Borg._instances[cls] = object.__new__(cls) > return Borg._instances[cls] > > > class WorkingSingleton(Borg): > > def __init__(self): > print(self.__class__.__name__, ':') > try: > self.already_initialized > print('already initialized') > return > > except AttributeError: > print('initializing') > > self.already_initialized = True > self.special_value = 42 > > > class FailingSingleton(Borg): > > def __init__(self): > print(self.__class__.__name__, ':') > try: > self.already_initialized:bool > print('already initialized') > return > > except AttributeError: > print('initializing') > > self.already_initialized = True > self.special_value = 42 > > s = WorkingSingleton() > print(s.special_value) > > s = FailingSingleton() > print(s.special_value) > > #------------------------------------------------------------ > > Notice how Working* and Failing differ in the type annotation > of self.already_initialized only. > > Output: > > WorkingSingleton : > initializing > 42 > > FailingSingleton : > already initialized <====================== Huh ? > Traceback (most recent call last): > File "/home/ncq/Projekte/gm/git/gnumed/gnumed/client/testing/test-singleton.py", line 48, in > print(s.special_value) > ^^^^^^^^^^^^^^^ > AttributeError: 'FailingSingleton' object has no attribute 'special_value' > > > Where's the error in my thinking (or code) ? What is your thinking? Specifically, what is the purpose of testing self.already_initialized? Isn't it generally regarded as 'best practice' to declare (and define a value for) all attributes in __init__()? (or equivalent) In which case, it will (presumably) be defined as False; and the try-except reworded to an if-else. Alternately, how about using hasattr()? eg if hasattr( self.already_initialized, 'attribute_name' ): # attribute is defined, etc As the code current stands, the: try: self.already_initialized line is flagged by the assorted linters, etc, in my PyCharm as: Statement seems to have no effect. Unresolved attribute reference 'already_initialized' for class 'WorkingSingleton'. but: self.already_initialized:bool passes without comment (see @Mats' response). Question: is it a legal expression (without the typing)? -- Regards, =dn From Karsten.Hilbert at gmx.net Sat Sep 30 18:25:11 2023 From: Karsten.Hilbert at gmx.net (Karsten Hilbert) Date: Sun, 1 Oct 2023 00:25:11 +0200 Subject: type annotation vs working code In-Reply-To: References: Message-ID: Am Sun, Oct 01, 2023 at 09:04:05AM +1300 schrieb dn via Python-list: > >class WorkingSingleton(Borg): > > > > def __init__(self): > > print(self.__class__.__name__, ':') > > try: > > self.already_initialized > > print('already initialized') > > return > > > > except AttributeError: > > print('initializing') > > > > self.already_initialized = True > > self.special_value = 42 > >Where's the error in my thinking (or code) ? > > What is your thinking? > Specifically, what is the purpose of testing self.already_initialized? The purpose is to check whether the singleton class has been ... initialized :-) The line self.already_initialized = True is misleading as to the fact that it doesn't matter at all what self.already_initialized is set to, as long as is exists for the next time around. > Isn't it generally regarded as 'best practice' to declare (and define a value for) all > attributes in __init__()? (or equivalent) In which case, it will (presumably) be defined > as False; and the try-except reworded to an if-else. I fail to see how that can differentiate between first-call and subsequent call. > Alternately, how about using hasattr()? eg > > if hasattr( self.already_initialized, 'attribute_name' ): That does work. I am using that idiom in other children of Borg. But that's besides the point. I was wondering why it does not work the same way with and without the type annotation. > try: > self.already_initialized > > line is flagged by the assorted linters, etc, in my PyCharm as: > > Statement seems to have no effect. Well, the linter simply cannot see the purpose, which is test-of-existence. > Question: is it a legal expression (without the typing)? It borders on the illegal, I suppose, as the self- introspection capabilities of the language are being leveraged to achieve a legal purpose. Which seems akin constructs for generating compatibility between versions. It seems the answer is being pointed to in Matts response. It just mightily surprised me. Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B From pau.vilchez.uso at gmail.com Mon Sep 25 12:58:12 2023 From: pau.vilchez.uso at gmail.com (Pau Vilchez) Date: Mon, 25 Sep 2023 12:58:12 -0400 Subject: Unable to completely remove Python 3.10.9 (64 bit) from Computer Message-ID: Hello Python Team, ? I am somehow unable to completely remove Python 3.10.9 (64 Bit) from my computer. I have tried deleting the Appdata folder then repairing and then uninstalling but it still persists in the remove/add program function in windows 10. I am just trying to reinstall it because I didn?t add it to the path correctly, any help is greatly appreciated. ? Very Respectfully, ? Pau Vilchez ?