Re: PEP668 / pipx and "--editable" installs
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 -- https://mail.python.org/mailman/listinfo/python-list
Re: pip/pip3 confusion and keeping up to date
Am Thu, Nov 02, 2023 at 09:35:43PM - schrieb Jon Ribbens via Python-list: Regardless of ... > Because pip barely plays well by itself, let alone with other package > managers at the same time. ... being true ... > > I do only install a few things using pip. > > Are they not available in your system's package manager? ... this clearly often answers to "no" for applications of any complexity. Is there a suggested proper path to deal with that (Debian is of interest to me here) ? Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B -- https://mail.python.org/mailman/listinfo/python-list
Re: pip/pip3 confusion and keeping up to date
Am Thu, Nov 02, 2023 at 04:07:33PM -0600 schrieb Mats Wichmann via Python-list: > >So they now have only python3 and there is no python executable in > >PATH. > > FWIW, for this you install the little stub package python-is-python3. > Especially if you > want to keep a python2 installation around - "python" will still be python3 > in this > case. Since you seem knowledgeable in this area: Do you know of a resource for learning the *canonical* way of packaging a Python application for installation via apt which - needs some packages available via apt - needs some packages only available via pip - needs some packages newer than what is available via apt ? Thanks, Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B -- https://mail.python.org/mailman/listinfo/python-list
Aw: Re: pip/pip3 confusion and keeping up to date
> > .From all the posts I gather the answer to my question is > > "simply": unpackaged-but-needed modules need to be packaged. > > I think there is one aspect that isn't getting consideration here. And > that is whether or not you want these packages installed in the default > system Python install. You might not. Indeed, which is why all the fuzz about how to fill-in a venv from pip while installing with apt :-) With "properly" packaged modules one wouldn't risk (that much) system breakage, at any rate. > Maybe you want to get the latest > possible version of super-dooper-gui-helper, but one of its dependencies > doesn't play well with the system Python libraries. Or ... but you get > the point. There are probably many cases where you want *not* to > install into the system Python world. So you would need to come up with > an APT-based installer that doesn't do that. > > Obviously it's not unthinkable; Certainly not, it's just that I had hoped someone goes: look here and all of this ... > it is just one more thing to figure out. ... has been thought through before. Thanks, Karsten -- https://mail.python.org/mailman/listinfo/python-list
Re: pip/pip3 confusion and keeping up to date
Am Sun, Nov 05, 2023 at 03:00:41PM + schrieb Chris Green via Python-list: > > * contact every single maintainer of every single one of the packages > > that needs updating and persuade them to update their packages and > > reassure them that you are getting all the other package maintainers > > to update their packages accordingly and that you have a plan and > > that you know what you're doing > > > > ... screen fades to black, title card "3 years later", fade in to ... > > > > * publish your package > > > Surely it's not that bad, the vast bulk of Debian, Ubuntu and other > distributions are installed via systems that sort out dependencies once > given a particular package's requirements. Python is surely not > unique in its dependency requirements. Oh, Debian does just fine in resolving dependencies it knows about within its .deb package universe. The problem arises when there's unpackaged modules required. The only answer seems to be to package such modules oneself. If that's been conquered a venv isn't even needed anymore. Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B -- https://mail.python.org/mailman/listinfo/python-list
Re: pip/pip3 confusion and keeping up to date
Am Fri, Nov 03, 2023 at 01:53:32PM - schrieb Jon Ribbens via Python-list: > >> Are they not available in your system's package manager? > > > > ... this clearly often answers to "no" for applications of > > any complexity. > > > > Is there a suggested proper path to deal with that (Debian is > > of interest to me here) ? > > Yes, as previously mentioned, use virtual environments. > > These days they don't even need to be "activated". For package 'foo' > for example you could create /usr/local/lib/foo, under which you would > create a virtual environment and install the 'foo' package inside it, > and then you could do: > > ln -s /usr/local/lib/foo/env/bin/foo /usr/local/bin/foo > > and then you could just type 'foo' to run it. This all being nice and well, but: How does one "fill" that venv with packages from pip during apt-get install python3-app-of-interest ? Is the suggested way really to pip-install into this venv during apt-get install ? Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B -- https://mail.python.org/mailman/listinfo/python-list
Re: pip/pip3 confusion and keeping up to date
Am Fri, Nov 03, 2023 at 05:26:06PM +0100 schrieb Dieter Maurer: > Karsten Hilbert wrote at 2023-11-3 14:47 +0100: > > ... > >> Are they not available in your system's package manager? > > > >... this clearly often answers to "no" for applications of > >any complexity. > > > >Is there a suggested proper path to deal with that (Debian is > >of interest to me here) ? > > Complex applications may maintain a set of "known workable versions" > associated with the application's releases. > They may describe those "known workable versions" in a `pip` constraint file. > In this case, you can upgrade to a new application release > by using this constraint file. Hello Dieter, do you happen to know where to read up on how to fit a pip constraint file into a Debian package creation workflow ? Thanks, Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B -- https://mail.python.org/mailman/listinfo/python-list
Re: pip/pip3 confusion and keeping up to date
Am Mon, Nov 06, 2023 at 01:17:11AM - schrieb Jon Ribbens via Python-list: > >> >> Are they not available in your system's package manager? > >> > > >> > ... this clearly often answers to "no" for applications of > >> > any complexity. > >> > > >> > Is there a suggested proper path to deal with that (Debian is > >> > of interest to me here) ? > >> > >> Yes, as previously mentioned, use virtual environments. > >> > > How does one "fill" that venv with packages from pip during > > > > apt-get install python3-app-of-interest > > > > ? > > > > Is the suggested way really to pip-install into this venv > > during apt-get install ? > > I don't know what you mean by that. But if you install the apt packages > and then create your venv with --system-site-packages then I believe > your venv should be able to see the apt packages and import them. The problem is when there's modules not available via apt as packages. In that case on needs to either package them or pip them into the venv suggested above. When they are apt-gettable no venv is needed in the first place. One would just install the application script like any other binary, and which loads apt-installed modules just so. Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B -- https://mail.python.org/mailman/listinfo/python-list
Re: pip/pip3 confusion and keeping up to date
Am Mon, Nov 06, 2023 at 08:58:00AM +0100 schrieb Dieter Maurer: > I know that debian packagers create debian packages > from Python distributions not using the approach sketched above > and likely they have their reasons. > > You might want to discuss this on an `apt` related mailing list. Yeah, I guess. I know all this stuff about python modules being packaged for Debian and how apt handles dependencies etc etc. I had just hoped someone here might have a handy pointer for how to deal with modules having to be installed from pip for use with an apt-installed python-based application. Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B -- https://mail.python.org/mailman/listinfo/python-list
Re: pip/pip3 confusion and keeping up to date
Am Mon, Nov 06, 2023 at 02:43:47PM -0700 schrieb Mats Wichmann via Python-list: > >I had just hoped someone here might have a handy pointer for > >how to deal with modules having to be installed from pip for > >use with an apt-installed python-based application. > > That just shouldn't happen - such packages are supposed to be > dependency-complete within > the packaging universe in question. Yep, that's the preferable ideal world. Which doesn't happen (but that's not the fault of anyone around here, no harm intended). .From all the posts I gather the answer to my question is "simply": unpackaged-but-needed modules need to be packaged. Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B -- https://mail.python.org/mailman/listinfo/python-list
Aw: Re: Any possible type alias that can also set a default value for a function arg?
> > or something like that. Basically, any way to avoid writing `= None` over > > and over again. > > Fundamentally no, at least not without some shenanigans. Type hints do > not affect the regular running of the code, Except when they do ;-) ... depending on what counts as (valid) code ... In Python a distinction can be made between "runnable" and "valid" :-D Karsten -- https://mail.python.org/mailman/listinfo/python-list
type annotation vs working code
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 -- https://mail.python.org/mailman/listinfo/python-list
Re: type annotation vs working code
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 -- https://mail.python.org/mailman/listinfo/python-list
Re: type annotation vs working code
Sorry for having conflated the core of the matter with all the Borg shenanigans, that's where I found the problem in my real code, so there :-) Consider this: # class Surprise: def __init__(self, with_type_annotation=False): if with_type_annotation: try: self.does_not_exist:bool print('does_not_exist does exist') except AttributeError: print('does_not_exist does not exist') return try: self.does_not_exist print('does_not_exist does exist') except AttributeError: print('does_not_exist does not exist') Surprise(with_type_annotation = False) Surprise(with_type_annotation = True) # Is this how it is supposed to be ? > ...and so we're addressing the important question: the try-test is for > existence, cf for > some value. > > This can also be achieved by using the attribute in a legal expression, eg: ... > Might this remove the confusion (ref: @Mats): > > self.already_initialized:bool == True Not for me as that would _create_ already_initialized on the instance. It would not allow me to test for it. > >Which seems akin constructs for generating compatibility > >between versions. > > versions of ? Of the language. Sometimes one tests for existence of a given class in a module and defines said class oneself if it does not exist. But that's leading astray. > What is the intent: a class where each instance is aware of every other > instance - yet > the word "Singleton" implies there's only one (cf a dict full of ...)? The latter. Regards, Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B -- https://mail.python.org/mailman/listinfo/python-list
Aw: Re: Re: Re: Any possible type alias that can also set a default value for a function arg?
> > As per my recent foray into abusing existence-checking for Singleton > > assurance > > along such lines as > > > > >>> try: self.initialized > > >>> except AttributeError: print('first instantiation'); self.initialized = > > >>> True > > > > and then changing that to > > > > >>> try: self.initialized:bool > > But that's not equivalent code. I learned as much (RHS vs LHS). But it did not _intuitively_ resonate with the sentiment "type annotation does not change the running of code". Karsten -- https://mail.python.org/mailman/listinfo/python-list
Aw: Re: Re: Any possible type alias that can also set a default value for a function arg?
> > > Fundamentally no, at least not without some shenanigans. Type hints do > > > not affect the regular running of the code, > > > > Except when they do ;-) > > > > ... depending on what counts as (valid) code ... > > > > In Python a distinction can be made between "runnable" and "valid" :-D > > > > Can you give a counter-example? As per my recent foray into abusing existence-checking for Singleton assurance along such lines as >>> try: self.initialized >>> except AttributeError: print('first instantiation'); self.initialized = True and then changing that to >>> try: self.initialized:bool Karsten -- https://mail.python.org/mailman/listinfo/python-list
Re: type annotation vs working code
Am Wed, Oct 04, 2023 at 05:25:04PM +1300 schrieb dn via Python-list: > The first question when dealing with the Singleton Pattern is what to do when > more than > one instantiation is attempted: > > - silently return the first instance This, in my case. > and so, returning to the matter of 'readability': > > - the name "Borg" de-railed comprehension > > - _instances:dict = {} implied the tracking of more than one Child classes, yes, each being a Singleton. > or a Singleton() class defined, which is then sub-classed, ie > > class Something( Singleton ): Could have been but the legacy codebase came with Borg ... > - from there, plenty of 'templates' exist for Singletons, ... which was taken from the Web ages ago. > - this article (https://python-patterns.guide/gang-of-four/singleton/) Reading. Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B -- https://mail.python.org/mailman/listinfo/python-list
Aw: Re: Re: mypy question
> I'm fairly sure your database queries don't actually give you strings or > dicts, right? You probably get lists (or iterators) of tuples and > somewhere you convert them to the arguments you are feeding to > run_queries(). Ah, no, those queries are enshrined within the middleware as Python strings with placeholdders. When in need of being run they are assembled into a list of dicts-enriched-with-arguments-per-query (and fed to run_queries()). As to what queries *give* me: I have set up psycopg2 to, indeed, hand me a list of dicts (DictRow instances, that is). Those are then used in display rather than being fed to run_queries(). Karsten -- https://mail.python.org/mailman/listinfo/python-list
Aw: Re: mypy question
Dear Thomas, thanks for taking the time to look into my issue. Maybe it helps if I explain what I want (sorry that my web mailer does not respect indentation, I will insert dots). I want a function to run SQL queries: run_queries(conn, queries): ...for q in queries: ..conn.execute(q) I now want to add type hints such that my large codebase can be checked for silly doings. First, queries is to be a list of the SQL to run: run_queries(conn, queries:list): Then, each list entry can be ...a string holding simple, complete SQL (say "SELECT 1") run_queries(conn, queries:list[str]): or ...a dict holding the SQL and arguments for parameters run_queries(conn, queries:list[dict]): So, taken together: run_queries(conn, queries:list[str|dict]): (yes, this is in Python 3.11/3.12) Now, when it is a list of dicts I want to further constrain the dicts. Each is to contain the keys "SQL" and "args". So the keys are of type str. The values for the keys will be of various types, such that I chose Any as pseudo-type, so that each list entry that is of type dict should be dict[str, Any], hence: queries = [{'SQL': 'SELECT %(value)s', 'args': {'value': 1}}] and run_queries(conn, queries:list[str|dict[str, Any]]): If I now call this function with a simple SQL query: SQL_query = 'SELECT 1' # should be type str ? queries = [SQL_query] # should be type list[str] ? run_queries(conn, queries = queries) and run mypy over that (at least inside my complex codebase) I will get a type mismatch being hinted at. So far I don't grasp at which point my reasoning above is faulty. Karsten -- https://mail.python.org/mailman/listinfo/python-list
Aw: Re: Re: mypy question
> It occurs to me that you could simplify things if you converted those > plain query strings to dicts: > > 'SELECT 1' --> {'SQL': 'SELECT 1'} Ha, indeed. There's likely not that many "simple string SQL queries" in that codebase so I shall take it as an opportunity to refactor them. So, at least that much good has come from the mypy hint ;-) Karsten -- https://mail.python.org/mailman/listinfo/python-list
Aw: Re: mypy question
Hi Greg, > dict[str, str] is not a subtype of dict[str, str | something_else] > because you can assign a value of type something_else to the latter > but not the former. I understand what you are saying but I do not yet understand why this applies to my situation. I don't have Python at hand currently, so I'll write untested pseudocode: def print_greeting(greeting:int|str): print(greeting) print_greeting('hello') The above snippet should be equivalent to my more complicated code over which mypy complains to the equivalent of "input" is of type "str" but expected type "Union[str,int] I do understand that "str" is formally more narrow than "Union [str,int]" and the type system has every right to not consider them equivalent. However, this seems like a very common use case: "allow passing in either str or int and have type checking pass either input as valid" -- yet mypy doesn't seem to share that idea. Or else there's something I haven't wrapped my head around yet. But what ? Karsten -- https://mail.python.org/mailman/listinfo/python-list
Re: mypy question
Thanks to all. I ended up using Sequence for the list part and Mapping for the dict part, which does require "import typing" which I would rather have avoided. Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B -- https://mail.python.org/mailman/listinfo/python-list
mypy question
Hi all, I am not sure why mypy thinks this gmPG2.py:554: error: Argument "queries" to "run_rw_queries" has incompatible type "List[Dict[str, str]]"; expected "List[Dict[str, Union[str, List[Any], Dict[str, Any" [arg-type] rows, idx = run_rw_queries(link_obj = conn, queries = queries, return_data = True) ^~~ should be flagged. The intent is for "queries" to be a list of dicts with keys of str and values of str OR list of anything OR dict with keys of str and values of anything I'd have thunk list[dict[str,str]] matches that ? This is on Python 3.11.2 with mypy 1.0.1 on Debian. Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B -- https://mail.python.org/mailman/listinfo/python-list
Re: mypy question
Am Fri, Dec 29, 2023 at 01:15:29PM +0100 schrieb Karsten Hilbert via Python-list: > I am not sure why mypy thinks this > > gmPG2.py:554: error: Argument "queries" to "run_rw_queries" has incompatible > type "List[Dict[str, str]]"; expected > "List[Dict[str, Union[str, List[Any], Dict[str, Any" [arg-type] > rows, idx = run_rw_queries(link_obj = conn, queries = > queries, return_data = True) > > ^~~ > > should be flagged. The intent is for "queries" to be > > a list > of dicts > with keys of str > and values of > str OR > list of anything OR > dict with > keys of str > and values of anything > > I'd have thunk list[dict[str,str]] matches that ? > > This is on Python 3.11.2 with mypy 1.0.1 on Debian. For completeness, this was the mypy call signature: mypy --pretty --allow-redefinition --no-strict-optional --ignore-missing-imports --follow-imports silent --show-error-codes --warn-unused-ignores gmPG2.py Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B -- https://mail.python.org/mailman/listinfo/python-list
Re: mypy question
Am Fri, Dec 29, 2023 at 07:49:17AM -0700 schrieb Mats Wichmann via Python-list: > >I am not sure why mypy thinks this > > > >gmPG2.py:554: error: Argument "queries" to "run_rw_queries" has incompatible > >type "List[Dict[str, str]]"; expected > >"List[Dict[str, Union[str, List[Any], Dict[str, Any" [arg-type] > > rows, idx = run_rw_queries(link_obj = conn, queries = > > queries, return_data = True) > > > > ^~~ > > > >should be flagged. The intent is for "queries" to be > > > >a list > > of dicts > > with keys of str > > and values of > > str OR > > list of anything OR > > dict with > > keys of str > > and values of anything > > > >I'd have thunk list[dict[str,str]] matches that ? > > Dict[str, str] means the key type and value type should both be strings, Indeed, I know that much, list[dict[str, str]] is what is getting passed in in this particular invocation of run_rw_queries(). For what it's worth here's the signature of that function: def run_rw_queries ( link_obj:_TLnkObj=None, queries:list[dict[str, str | list | dict[str, Any]]]=None, end_tx:bool=False, return_data:bool=None, get_col_idx:bool=False, verbose:bool=False ) -> tuple[list[dbapi.extras.DictRow], dict[str, int] | None]: Given that I would have thought that passing in list[dict[str, str]] for "queries" ought to be type safe. Mypy indicates otherwise which I am not grokking as to why. > but in your > retelling above you indicate lots of possible value types... actually the > mypy guess > seems to be a pretty good recreation of your psuedo-code description. I agree that mypy's grasp of my intent from queries:list[dict[str, str | list | dict[str, Any]]]=None, into "List[Dict[str, Union[str, List[Any], Dict[str, Any" seems accurate. I just don't understand why list[dict[str, str]] should not pass that construct. Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B -- https://mail.python.org/mailman/listinfo/python-list
Re: mypy question
Am Fri, Dec 29, 2023 at 11:04:59AM -0700 schrieb Mats Wichmann via Python-list: > >For what it's worth here's the signature of that function: > > > > def run_rw_queries ( > > link_obj:_TLnkObj=None, > > queries:list[dict[str, str | list | dict[str, Any]]]=None, > > end_tx:bool=False, > > return_data:bool=None, > > get_col_idx:bool=False, > > verbose:bool=False > > ) -> tuple[list[dbapi.extras.DictRow], dict[str, int] | None]: > > > >Given that I would have thought that passing in > >list[dict[str, str]] for "queries" ought to be type safe. > >Mypy indicates otherwise which I am not grokking as to why. > > ah... didn't grok what you were asking, sorry - ignore my attempt then. Never mind, the attempt to help is appreciated. > So you are passing something that has been typed more > narrowly than the function parameter. That would then sort of skirt on violation of the Liskov principle, of which I learned while trying to research this mypy behaviour. However, I would not think the above to be a narrowing-down as it just *selects* one of the explicitely "legal" options. list[dict[str, str | list | dict[str, Any]]] should AFAICT expand to: list[dict[str, dict[str, Any]]] OR list[dict[str, list]] OR list[dict[str, str]] the last of which should provide coverage of [{'some key': 'some value'}] > Can you use a TypeGuard here? Not from what I understand about them... Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B -- https://mail.python.org/mailman/listinfo/python-list
Re: mypy question
Am Fri, Jan 12, 2024 at 02:23:43PM +0100 schrieb Antoon Pardon via Python-list: > > queries:list[dict[str, str | list | dict[str, Any]]]=None, > > > >into > > > > "List[Dict[str, Union[str, List[Any], Dict[str, Any" > > > >seems accurate. I just don't understand why list[dict[str, > >str]] should not pass that construct. > > Sorry for the late reaction ne'er mind ya > I was wondering if > your type hint for queries shouldn't be the following. > > queries:list[dict[str,str]|dict[str,list]|dict[str,dict[str, dict[str, Ant]]] > > My impression at this moment is that you are write something like: dict[str, > str | int] as > as shorthand for dict[str, str] | dict[str, int]. I do. > But those two are different types. A-ha ! In what way ? Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B -- https://mail.python.org/mailman/listinfo/python-list
Re: mypy question
Am Sat, Jan 13, 2024 at 09:20:00PM +0100 schrieb Karsten Hilbert via Python-list: > > I was wondering if > > your type hint for queries shouldn't be the following. > > > > queries:list[dict[str,str]|dict[str,list]|dict[str,dict[str, dict[str, > > Ant]]] Wait, not really. Let me give an example. Here's three times the same query (as far as PostgreSQL is concerned, after having been passed through psycopg2): queries = [ { 'SQL': 'SELECT 1' }, { 'SQL': 'SELECT %s', 'args': [1] }, { 'SQL': 'SELECT %(value)s', 'args': {'value': 1} } ] The value for key "SQL" will always be str-like. The value for "args" can be a list or a dict itself. If "args" is a dict it will be of type [str, Any]. That's what I am trying to tell mypy. Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B -- https://mail.python.org/mailman/listinfo/python-list
Aw: Re: Re: Extract lines from file, add to new files
> > Why not foxus on just the part you think you are better off using python, > > namely personalization ? > > > > Create personalized files and send them with your trusted mailx solution ? > > Karsten, > > Too much time. And while mailx accepts the '-a' option for attachments but > has none for individual salutations. It doesn't need to. It just sends the (pre-personalized-by-Python) mail files. Karsten -- https://mail.python.org/mailman/listinfo/python-list
Aw: Re: Re: Re: Extract lines from file, add to new files
> On Tue, 30 Jan 2024, Karsten Hilbert wrote: > > > It doesn't need to. It just sends the (pre-personalized-by-Python) mail > > files. > > Karsten, > > In which case, I might as well have Python format and send the messages. :-) Certainly. But it seems you are wrestling with Python. Might as well reduce the attack surface. Karsten -- https://mail.python.org/mailman/listinfo/python-list
Aw: Re: Extract lines from file, add to new files
> For 30 years I've used a bash script using mailx to send messages to a list > of recipients. They have no salutation to personalize each one. Since I want > to add that personalized salutation I decided to write a python script to > replace the bash script. Why not foxus on just the part you think you are better off using python, namely personalization ? Create personalized files and send them with your trusted mailx solution ? That'll take out wrestling with smptlib et al. Karsten -- https://mail.python.org/mailman/listinfo/python-list
Re: Terminal Emulator (Posting On Python-List Prohibited)
Am Sun, May 19, 2024 at 10:45:09PM +0100 schrieb Barry via Python-list: > > On 18 May 2024, at 16:27, Peter J. Holzer via Python-list > > wrote: > > > > I don't think Linux users have to deal with venvs > > Modern debian (ubuntu) and fedora block users installing using pip. > You must use a venv to pip install packages from pypi now. Which makes one wonder how one is supposed to package Python applications requiring modules not yet packaged by Debian. Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B -- https://mail.python.org/mailman/listinfo/python-list