From 64c66834c93fbf28a9fb89e5ee7dcc0bb17328b9 Mon Sep 17 00:00:00 2001 From: frostming Date: Tue, 1 Sep 2020 16:45:19 +0800 Subject: [PATCH] ensure dict keys are hashable --- news/4446.bugfix.rst | 1 + pipenv/vendor/requirementslib/models/setup_info.py | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 news/4446.bugfix.rst diff --git a/news/4446.bugfix.rst b/news/4446.bugfix.rst new file mode 100644 index 00000000..d89fe4b0 --- /dev/null +++ b/news/4446.bugfix.rst @@ -0,0 +1 @@ +Fix a bug that function calls in ``setup.py`` can't be parsed rightly. diff --git a/pipenv/vendor/requirementslib/models/setup_info.py b/pipenv/vendor/requirementslib/models/setup_info.py index 2bce837f..4a5fe771 100644 --- a/pipenv/vendor/requirementslib/models/setup_info.py +++ b/pipenv/vendor/requirementslib/models/setup_info.py @@ -992,6 +992,15 @@ class Analyzer(ast.NodeVisitor): return setup +def _ensure_hashable(item): + try: + hash(item) + except TypeError: + return str(item) + else: + return item + + def ast_unparse(item, initial_mapping=False, analyzer=None, recurse=True): # noqa:C901 # type: (Any, bool, Optional[Analyzer], bool) -> Union[List[Any], Dict[Any, Any], Tuple[Any, ...], STRING_TYPE] unparse = partial( @@ -1003,7 +1012,7 @@ def ast_unparse(item, initial_mapping=False, analyzer=None, recurse=True): # no constant = ast.Ellipsis unparsed = item if isinstance(item, ast.Dict): - unparsed = dict(zip(unparse(item.keys), unparse(item.values))) + unparsed = dict(zip(map(_ensure_hashable, unparse(item.keys)), unparse(item.values))) elif isinstance(item, ast.List): unparsed = [unparse(el) for el in item.elts] elif isinstance(item, ast.Tuple):