Aw: Re: mypy question

Thomas Passin list1 at tompassin.net
Sat Dec 30 11:57:15 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]):

It occurs to me that you could simplify things if you converted those 
plain query strings to dicts:

'SELECT 1' --> {'SQL': 'SELECT 1'}

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().  At least, that is how the standard Python db adapters 
work. If you change that conversion step, your arguments to 
run_queries() will all be lists of dicts, making your code simpler and 
reducing the complexity of the type hints.

> 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



More information about the Python-list mailing list