Let argument destructuring work with docstrings

This commit is contained in:
Rob Day 2017-09-16 21:06:58 +01:00
parent cfdd321f9a
commit 907e72681f
3 changed files with 31 additions and 0 deletions

1
NEWS
View File

@ -44,6 +44,7 @@ Changes from 0.13.0
instead of silently ignoring them
* Multiple expressions are now allowed in the else clause of
a for loop
* Argument destructuring no longer interferes with function docstrings.
[ Misc. Improvements ]
* `read`, `read_str`, and `eval` are exposed and documented as top-level

View File

@ -1881,6 +1881,10 @@ class HyASTCompiler(object):
force_functiondef = expression.pop(0) == "fn*"
arglist = expression.pop(0)
docstring = None
if len(expression) > 1 and isinstance(expression[0], str_type):
docstring = expression.pop(0)
if not isinstance(arglist, HyList):
raise HyTypeError(expression,
"First argument to `fn' must be a list")
@ -1901,6 +1905,11 @@ class HyASTCompiler(object):
) + expression
expression = expression.replace(arg[0])
# Docstrings must come at the start, so ensure that happens even if we
# generate anonymous variables.
if docstring is not None:
expression.insert(0, docstring)
if PY3:
# Python 3.4+ requires that args are an ast.arg object, rather
# than an ast.Name or bare string.

View File

@ -1660,3 +1660,24 @@
[_42 6])
(setv x (XYZ))
(assert (= (. x _42) 6)))
(defn test-docstrings []
"Make sure docstrings in functions work and don't clash with return values"
(defn f [] "docstring" 5)
(assert (= (. f __doc__) "docstring"))
; destructuring and the implicit variables it creates
; shouldn't interfere with docstrings
; (https://github.com/hylang/hy/issues/1409)
(defn f2 [[a b]] "docstring" 5)
(assert (= (. f2 __doc__) "docstring"))
; a single string is the return value, not a docstring
; (https://github.com/hylang/hy/issues/1402)
(defn f3 [] "not a docstring")
(assert (none? (. f3 __doc__)))
(assert (= (f3) "not a docstring"))
(defn f4 [[a b]] "not a docstring")
(assert (none? (. f4 __doc__)))
(assert (= (f4 [1 2]) "not a docstring")))