From: Daniele Varrazzo Date: Wed, 30 Dec 2020 02:53:23 +0000 (+0100) Subject: Fast-path in query preparation to skip expensive isinstance X-Git-Tag: 3.0.dev0~225 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2224d3a1decddda68f7fc9bfe6467ddb7d21d881;p=thirdparty%2Fpsycopg.git Fast-path in query preparation to skip expensive isinstance --- diff --git a/psycopg3/psycopg3/_queries.py b/psycopg3/psycopg3/_queries.py index ab3b784fd..2828471bb 100644 --- a/psycopg3/psycopg3/_queries.py +++ b/psycopg3/psycopg3/_queries.py @@ -164,7 +164,23 @@ def _validate_and_reorder_params( """ Verify the compatibility between a query and a set of params. """ - if isinstance(vars, Sequence) and not isinstance(vars, (bytes, str)): + # Try concrete types, then abstract types + t = type(vars) + if t is list or t is tuple: + sequence = True + elif t is dict: + sequence = False + elif isinstance(vars, Sequence) and not isinstance(vars, (bytes, str)): + sequence = True + elif isinstance(vars, Mapping): + sequence = False + else: + raise TypeError( + f"query parameters should be a sequence or a mapping," + f" got {type(vars).__name__}" + ) + + if sequence: if len(vars) != len(parts) - 1: raise e.ProgrammingError( f"the query has {len(parts) - 1} placeholders but" @@ -174,27 +190,23 @@ def _validate_and_reorder_params( raise TypeError( "named placeholders require a mapping of parameters" ) - return vars + return vars # type: ignore[return-value] - elif isinstance(vars, Mapping): + else: if vars and len(parts) > 1 and not isinstance(parts[0][1], str): raise TypeError( "positional placeholders (%s) require a sequence of parameters" ) try: - return [vars[item] for item in order or ()] + return [ + vars[item] for item in order or () # type: ignore[call-overload] + ] except KeyError: raise e.ProgrammingError( f"query parameter missing:" f" {', '.join(sorted(i for i in order or () if i not in vars))}" ) - else: - raise TypeError( - f"query parameters should be a sequence or a mapping," - f" got {type(vars).__name__}" - ) - _re_placeholder = re.compile( rb"""(?x)