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.
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
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.
Ah, I think you've hit on the problem there. Consider this:
def add_item(stuff: dict[str: str | int]):
stuff["spam"] = "ham"
stuff["vooom"] = 1_000_000
Sysop: | Tetrazocine |
---|---|
Location: | Melbourne, VIC, Australia |
Users: | 6 |
Nodes: | 8 (0 / 8) |
Uptime: | 45:39:53 |
Calls: | 45 |
Files: | 21,492 |
Messages: | 63,512 |