From 69f3e4ee6eeba6b8a02dd130b2025237bec815cb Mon Sep 17 00:00:00 2001 From: Brett Smith Date: Mon, 15 Mar 2021 09:55:32 -0400 Subject: [PATCH] query: Add a hint for the TypeError `unhashable type: 'set'`. --- conservancy_beancount/reports/query.py | 35 +++++++++++++++++++------- setup.py | 2 +- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/conservancy_beancount/reports/query.py b/conservancy_beancount/reports/query.py index 9ea5052..75749d8 100644 --- a/conservancy_beancount/reports/query.py +++ b/conservancy_beancount/reports/query.py @@ -556,15 +556,12 @@ class BQLShell(bc_query_shell.BQLShell): ) except Exception as error: logger.error(str(error), exc_info=logger.isEnabledFor(logging.DEBUG)) - if (isinstance(error, TypeError) - and error.args - and ' not supported between instances ' in error.args[0]): - logger.info( - "HINT: Are you using ORDER BY or comparisons with metadata " - "that isn't consistently set?\n " - "Try looking up that metadata with str_meta() instead to " - "ensure your comparisons use a consistent data type.", - ) + try: + hint_func = getattr(self, f'_hint_{type(error).__name__}') + except AttributeError: + pass + else: + hint_func(error, statement) return if not rows and output_format != 'ods': @@ -573,6 +570,26 @@ class BQLShell(bc_query_shell.BQLShell): logger.debug("rendering query as %s", output_format) render_func(statement, row_types, rows) + def _hint_TypeError(self, error: TypeError, statement: QueryStatement) -> None: + try: + errmsg = str(error.args[0]) + except IndexError: + return + if ' not supported between instances ' in errmsg: + logger.info( + "HINT: Are you using ORDER BY or comparisons with metadata " + "that isn't consistently set?\n " + "Try looking up that metadata with str_meta() instead to " + "ensure your comparisons use a consistent data type.", + ) + elif errmsg.startswith('unhashable type: '): + logger.info( + "HINT: bean-query does not support selecting columns or " + "functions that return multiple items as non-aggregate data in " + "GROUP BY queries.\n " + "If you want to aggregate that data, run it through set().", + ) + def _render_csv(self, statement: QueryStatement, row_types: RowTypes, rows: Rows) -> None: bc_query_render.render_csv( row_types, diff --git a/setup.py b/setup.py index d55c9be..5e0f4bf 100755 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ from setuptools import setup setup( name='conservancy_beancount', description="Plugin, library, and reports for reading Conservancy's books", - version='1.19.3', + version='1.19.4', author='Software Freedom Conservancy', author_email='info@sfconservancy.org', license='GNU AGPLv3+',