Aw: Re: mypy question

Thomas Passin list1 at tompassin.net
Sat Dec 30 11:17:12 EST 2023


On 12/30/2023 10:08 AM, Karsten Hilbert via Python-list wrote:
> 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

I am not very expert in Python type hints.  In working up the example 
program I just posted, I got an error message from mypy that remarked 
that "list" is invariant, and to try Sequence which is "covariant".  I 
don't know what that means (and I haven't looked into it yet), but when 
I changed from list to Sequence as suggested, mypy stopped complaining.

Here is the exact error message, and it has a reference you might want 
to follow up with:

c:\temp\python\typing_test.py:16: note: "List" is invariant -- see 
https://mypy.readthedocs.io/en/stable/common_issues.html#variance
c:\temp\python\typing_test.py:16: note: Consider using "Sequence" 
instead, which is covariant

Before that, mypy insisted that str and Union[str, list] were 
incompatible argument types, which is something you are seeing, too.

I suggest that you build up your types as in my example, so that it's 
very clear what they are and very easy to change them, and use Sequence 
instead of List (or list).  See if that will do the job.



More information about the Python-list mailing list