juliadocs / docstringextensions.jl Goto Github PK
View Code? Open in Web Editor NEWExtensions for Julia's docsystem.
Home Page: https://DocStringExtensions.juliadocs.org/latest
License: Other
Extensions for Julia's docsystem.
Home Page: https://DocStringExtensions.juliadocs.org/latest
License: Other
Naturally $(SIGNATURES)
cannot be expanded when used with @doc raw
in a docstring in which TeX commands are used. I wonder if there is a workaround to this.
using DocStringExtensions
@doc raw"""
$(SIGNATURES)
Returns
```math
f(σ) = \dfrac{x}{y + 1}
"""
f(x, y) = x / (y + 1)
This is a great extension! :) I've noticed a few open source projects that don't have function signatures in their docstrings, and I think this package could help a lot.
To help make it easier for me to contribute to these projects, I'd like to write a CLI script that will:
If I made such a script, and if it worked well (did the right thing 90% of the time, with the other 10% manually fixable), would it be welcomed to be bundled in with DocStringExtensions for others to use as well?
Thanks for the great package!
I found an annoying issue on 0.6 related to UnionAll
types. If you use SIGNATURES
as follows:
using DocStringExtensions
"""
$(SIGNATURES)
"""
function f(::Type{T}) where {T}
T
end
then ?f
results in
ERROR: type UnionAll has no field parameters
Stacktrace:
[1] to_tuple_type(::Any) at ./reflection.jl:468
[2] methods(::Any, ::Any) at ./reflection.jl:583
[3] getmethods!(::Array{Method,1}, ::Function, ::Type{T} where T) at /home/twan/code/RigidBodyDynamics/v0.6/DocStringExtensions/src/utilities.jl:86
[4] #methodgroups#3(::Bool, ::Function, ::Function, ::Type{T} where T, ::Module) at /home/twan/code/RigidBodyDynamics/v0.6/DocStringExtensions/src/utilities.jl:24
[5] format(::DocStringExtensions.MethodSignatures, ::Base.AbstractIOBuffer{Array{UInt8,1}}, ::Base.Docs.DocStr) at /home/twan/code/RigidBodyDynamics/v0.6/DocStringExtensions/src/abbreviations.jl:290
[6] formatdoc(::Base.AbstractIOBuffer{Array{UInt8,1}}, ::Base.Docs.DocStr, ::DocStringExtensions.MethodSignatures) at /home/twan/code/RigidBodyDynamics/v0.6/DocStringExtensions/src/abbreviations.jl:25
[7] formatdoc(::Base.Docs.DocStr) at ./docs/Docs.jl:178
[8] parsedoc(::Base.Docs.DocStr) at ./docs/Docs.jl:186
[9] _collect(::Array{Base.Docs.DocStr,1}, ::Base.Generator{Array{Base.Docs.DocStr,1},Base.Docs.#parsedoc}, ::Base.EltypeUnknown, ::Base.HasShape) at ./array.jl:454
[10] doc(::Base.Docs.Binding, ::Type{T} where T) at ./docs/Docs.jl:312
[11] doc(::Base.Docs.Binding) at ./docs/Docs.jl:280
This is because the sig
passed into getmethods!
is Union{Tuple{Type{T}}, Tuple{T}} where T
, which is a UnionAll
, not a Union
.
When I have several methods, for example:
"""
$(SIGNATURES)
Print-fu.
"""
foo(x::Int) = print(x)
foo(x::Int, y::Int) = print(x + y)
I get
foo(x)
Print-fu.
But I am looking for an implementation that yields
foo(x)
foo(x, y)
Print-fu.
Is this possible at all?
$TYPEDSIGNATURES
causes error when calling Base.return_type
when typesig is UnionAll
with generic types.
I think the easy hacky solution to this is to wrap the following in a try except.
DocStringExtensions.jl/src/utilities.jl
Lines 308 to 311 in 339cd6d
A better solution is to pass the right typesig
to Base.return_types
. The issue here is that local typesig = doc.data[:typesig]
doesn't exactly return what we want. And I think we are currently missing some corner case. Specifically, generic UnionAll
types are converted to Tuple
s without the TypeVar
var. This causes some issues.
I'm not able to reproduce an example in isolation, since I believe it is tied to return_types
, which depends on the code path. But the function signature looks something like this.
"""
$TYPEDSIGNATURES
"""
function f(x::ParametricType{M}) where M <: Union{A, B}
...
return result
end
calls Base.return_types
throws an exception in the core compiler.
help?> Module.f
ERROR: TypeError: in <:, expected Type, got a value of type TypeVar
Stacktrace:
[1] ⊑(::Any, ::Any) at ./compiler/typelattice.jl:177
[2] tmerge(::Any, ::Any) at ./compiler/typelimits.jl:286
[3] getfield_tfunc(::Any, ::Any) at ./compiler/tfuncs.jl:827
[4] builtin_tfunction(::Any, ::Array{Any,1}, ::Union{Nothing, Core.Compiler.InferenceState}, ::Core.Compiler.Params) at ./compiler/tfuncs.jl:1428
[5] builtin_tfunction at ./compiler/tfuncs.jl:1342 [inlined]
[6] abstract_call_known(::Any, ::Array{Any,1}, ::Array{Any,1}, ::Array{Any,1}, ::Core.Compiler.InferenceState, ::Int64) at ./compiler/abstractinterpretation.jl:720
[7] abstract_call(::Array{Any,1}, ::Array{Any,1}, ::Array{Any,1}, ::Core.Compiler.InferenceState, ::Int64) at ./compiler/abstractinterpretation.jl:926
[8] abstract_call(::Array{Any,1}, ::Array{Any,1}, ::Array{Any,1}, ::Core.Compiler.InferenceState) at ./compiler/abstractinterpretation.jl:911
[9] abstract_eval(::Any, ::Array{Any,1}, ::Core.Compiler.InferenceState) at ./compiler/abstractinterpretation.jl:1005
[10] typeinf_local(::Core.Compiler.InferenceState) at ./compiler/abstractinterpretation.jl:1270
[11] typeinf_nocycle(::Core.Compiler.InferenceState) at ./compiler/abstractinterpretation.jl:1326
[12] typeinf(::Core.Compiler.InferenceState) at ./compiler/typeinfer.jl:12
[13] typeinf_edge(::Method, ::Any, ::Core.SimpleVector, ::Core.Compiler.InferenceState) at ./compiler/typeinfer.jl:484
[14] abstract_call_method(::Method, ::Any, ::Core.SimpleVector, ::Bool, ::Core.Compiler.InferenceState) at ./compiler/abstractinterpretation.jl:419
[15] abstract_call_gf_by_type(::Any, ::Array{Any,1}, ::Any, ::Core.Compiler.InferenceState, ::Int64) at ./compiler/abstractinterpretation.jl:111
[16] abstract_call_known(::Any, ::Array{Any,1}, ::Array{Any,1}, ::Array{Any,1}, ::Core.Compiler.InferenceState, ::Int64) at ./compiler/abstractinterpretation.jl:904
[17] abstract_call(::Array{Any,1}, ::Array{Any,1}, ::Array{Any,1}, ::Core.Compiler.InferenceState, ::Int64) at ./compiler/abstractinterpretation.jl:926
[18] abstract_call(::Array{Any,1}, ::Array{Any,1}, ::Array{Any,1}, ::Core.Compiler.InferenceState) at ./compiler/abstractinterpretation.jl:911
[19] abstract_eval(::Any, ::Array{Any,1}, ::Core.Compiler.InferenceState) at ./compiler/abstractinterpretation.jl:1005
[20] typeinf_local(::Core.Compiler.InferenceState) at ./compiler/abstractinterpretation.jl:1270
[21] typeinf_nocycle(::Core.Compiler.InferenceState) at ./compiler/abstractinterpretation.jl:1326
[22] typeinf(::Core.Compiler.InferenceState) at ./compiler/typeinfer.jl:12
[23] typeinf_edge(::Method, ::Any, ::Core.SimpleVector, ::Core.Compiler.InferenceState) at ./compiler/typeinfer.jl:484
[24] abstract_call_method(::Method, ::Any, ::Core.SimpleVector, ::Bool, ::Core.Compiler.InferenceState) at ./compiler/abstractinterpretation.jl:419
[25] abstract_call_gf_by_type(::Any, ::Array{Any,1}, ::Any, ::Core.Compiler.InferenceState, ::Int64) at ./compiler/abstractinterpretation.jl:111
[26] abstract_call_known(::Any, ::Array{Any,1}, ::Array{Any,1}, ::Array{Any,1}, ::Core.Compiler.InferenceState, ::Int64) at ./compiler/abstractinterpretation.jl:904
[27] abstract_call(::Array{Any,1}, ::Array{Any,1}, ::Array{Any,1}, ::Core.Compiler.InferenceState, ::Int64) at ./compiler/abstractinterpretation.jl:926
[28] abstract_call(::Array{Any,1}, ::Array{Any,1}, ::Array{Any,1}, ::Core.Compiler.InferenceState) at ./compiler/abstractinterpretation.jl:911
[29] abstract_eval(::Any, ::Array{Any,1}, ::Core.Compiler.InferenceState) at ./compiler/abstractinterpretation.jl:1005
[30] typeinf_local(::Core.Compiler.InferenceState) at ./compiler/abstractinterpretation.jl:1270
[31] typeinf_nocycle(::Core.Compiler.InferenceState) at ./compiler/abstractinterpretation.jl:1326
[32] typeinf(::Core.Compiler.InferenceState) at ./compiler/typeinfer.jl:12
[33] typeinf at ./compiler/typeinfer.jl:8 [inlined]
[34] typeinf_type(::Method, ::Any, ::Core.SimpleVector, ::Core.Compiler.Params) at ./compiler/typeinfer.jl:592
[35] return_types(::Any, ::Any) at ./reflection.jl:1133
[36] printmethod(::Base.GenericIOBuffer{Array{UInt8,1}}, ::Base.Docs.Binding, ::Function, ::Method, ::Type{T} where T) at /Users/USER/.julia/packages/DocStringExtensions/c3W3t/src/utilities.jl:308
[37] format(::DocStringExtensions.TypedMethodSignatures, ::Base.GenericIOBuffer{Array{UInt8,1}}, ::Base.Docs.DocStr) at /Users/USER/.julia/packages/DocStringExtensions/c3W3t/src/abbreviations.jl:391
[38] formatdoc(::Base.GenericIOBuffer{Array{UInt8,1}}, ::Base.Docs.DocStr, ::DocStringExtensions.TypedMethodSignatures) at /Users/USER/.julia/packages/DocStringExtensions/c3W3t/src/abbreviations.jl:25
[39] format(::DocStringExtensions.Template{:before}, ::Base.GenericIOBuffer{Array{UInt8,1}}, ::Base.Docs.DocStr) at /Users/USER/.julia/packages/DocStringExtensions/c3W3t/src/abbreviations.jl:639
[40] formatdoc(::Base.GenericIOBuffer{Array{UInt8,1}}, ::Base.Docs.DocStr, ::DocStringExtensions.Template{:before}) at /Users/USER/.julia/packages/DocStringExtensions/c3W3t/src/abbreviations.jl:25
[41] formatdoc(::Base.Docs.DocStr) at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.5/REPL/src/docview.jl:83
[42] parsedoc(::Base.Docs.DocStr) at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.5/REPL/src/docview.jl:91
[43] iterate at ./generator.jl:47 [inlined]
[44] _collect(::Array{Base.Docs.DocStr,1}, ::Base.Generator{Array{Base.Docs.DocStr,1},typeof(Base.Docs.parsedoc)}, ::Base.EltypeUnknown, ::Base.HasShape{1}) at ./array.jl:699
[45] collect_similar at ./array.jl:628 [inlined]
[46] map at ./abstractarray.jl:2162 [inlined]
[47] doc(::Base.Docs.Binding, ::Type{T} where T) at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.5/REPL/src/docview.jl:185
[48] doc(::Base.Docs.Binding) at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.5/REPL/src/docview.jl:153
[49] top-level scope at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.5/REPL/src/docview.jl:438
I'll take a closer look at this when I get the chance.
Related: #88
We still have the Appveyor and Travis badges there, even though we're using GitHub Actions now.
The following fails (tested on 1.6.5 and on nightly):
module MWE
using DocStringExtensions
@template METHODS =
"""
$(DOCSTRING)
$(TYPEDSIGNATURES)
"""
"Docstring."
@generated f(x) = :(2 * $(length(x)))
end
help?> MWE.f
ERROR: Method is @generated; try `code_lowered` instead.
Stacktrace:
[1] error(s::String)
@ Base ./error.jl:33
[2] uncompressed_ir(m::Method)
@ Base ./reflection.jl:988
[3] get_method_source
@ ~/.julia/packages/DocStringExtensions/iscC8/src/utilities.jl:354 [inlined]
[4] arguments(m::Method)
@ DocStringExtensions ~/.julia/packages/DocStringExtensions/iscC8/src/utilities.jl:434
[5] format(#unused#::DocStringExtensions.TypedMethodSignatures, buf::IOBuffer, doc::Base.Docs.DocStr)
@ DocStringExtensions ~/.julia/packages/DocStringExtensions/iscC8/src/abbreviations.jl:381
[6] formatdoc(buf::IOBuffer, doc::Base.Docs.DocStr, part::DocStringExtensions.TypedMethodSignatures)
@ DocStringExtensions ~/.julia/packages/DocStringExtensions/iscC8/src/abbreviations.jl:25
[7] format(abbr::DocStringExtensions.Template{:after}, buf::IOBuffer, doc::Base.Docs.DocStr)
@ DocStringExtensions ~/.julia/packages/DocStringExtensions/iscC8/src/abbreviations.jl:647
[8] formatdoc(buf::IOBuffer, doc::Base.Docs.DocStr, part::DocStringExtensions.Template{:after})
@ DocStringExtensions ~/.julia/packages/DocStringExtensions/iscC8/src/abbreviations.jl:25
[9] formatdoc(d::Base.Docs.DocStr)
@ REPL /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/docview.jl:88
[10] parsedoc(d::Base.Docs.DocStr)
@ REPL /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/docview.jl:96
[11] map!(f::typeof(Base.Docs.parsedoc), dest::Vector{Any}, A::Vector{Base.Docs.DocStr})
@ Base ./abstractarray.jl:2287
[12] mapany
@ ./abstractarray.jl:2296 [inlined]
[13] doc(binding::Base.Docs.Binding, sig::Type)
@ REPL /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/docview.jl:192
[14] doc(binding::Base.Docs.Binding)
@ REPL /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/docview.jl:160
[15] top-level scope
@ /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/docview.jl:476
We could check if the method is generated, and if so, adapt how we extract arguments.
It may be useful to add a SUBTYPES
abbreviation that expands to something like
subtypes: [`SubType1`](@ref), [`SubType2`](@ref), ...
I wonder if it would it make sense to allow
"""
$(SIGNATURES)
"""
Base.@kwdef struct Foo
a
b
end
document the constructors of Foo
. This would be especially useful when there is not other explicit outer or inner constructor.
Consider the following documentation for a function f1
in a module CGP
"""
$(TYPEDSIGNATURES)
"""
function f1(a::Int, b::Int=0)
return a + b
end
The generated documentation is
Two signatures are produced, but information of the default value is lost. I have to document the default value of b
manually.
Is it possible to produce a single signature that contains the default value? Something like follows
f1(a::Int64, b::Int64=0) -> Int64
I would really like to be able to do this.
"""
$(SIGNATURES)
"""
func(x, y::Real; z::Float64=10.0) = x + y + z
And have the docstring be
func(x, y::Real; z::Float64)
This seems feasible, any chance we can do this?
This issue is used to trigger TagBot; feel free to unsubscribe.
If you haven't already, you should update your TagBot.yml
to include issue comment triggers.
Please see this post on Discourse for instructions and more details.
If you'd like for me to do this for you, comment TagBot fix
on this issue.
I'll open a PR within a few hours, please be patient!
Is there a way to generate formatted docstrings using DocStringExtensions.jl
? For example, in a package we are currently developing our docstrings are defined like this:
"""
add_reactions(
m::CoreModel,
s::V1,
b::V2,
c::AbstractFloat,
xl::AbstractFloat,
xu::AbstractFloat;
check_consistency = false,
) where {V1<:VecType,V2<:VecType}
Add reaction(s) to a `CoreModel` model `m`.
"""
but we would like to make use of DocStringExtentions.jl
like this:
"""
$(TYPEDSIGNATURES)
Add reaction(s) to a `CoreModel` model `m`.
"""
However, the generated docstrings look like this:
help?> add_reactions
search: add_reactions add_reactions! @add_reactions! with_added_reactions add_reaction!
add_reactions(m::CoreModel, s::V1<:AbstractVector{Float64}, b::V2<:AbstractVector{Float64}, c::AbstractFloat, xl::AbstractFloat, xu::AbstractFloat; check_consistency) -> Union{CoreModel, Tuple{CoreModel, Vector{Int64}, Vector{Int64}}}
Add reaction(s) to a CoreModel model m.
which makes it difficult to read. It would be great if we could format them somehow. Is there functionality for this?
The v0.1 version of the documentation is the first result in a Google search for "docstringextensions" and the the third result for "docstringextensions.jl". This is very confusing because that page is not labeled with the version number and does not contain links to any of the other versions (was created with MkDocs, not Documenter.jl
), which could lead users to believe it is for the most recent version. It might be a good idea to remove it from gh-pages
or at least rebuild it with Documenter.jl
.
At the moment there are no tests for #73, right?
Base.@kwdef
uses@__doc__
so this should cover that issue.Originally posted by @MichaelHatherly in #96 (comment)
Compared DocStringExtensions from current release and from master. In both cases, this
import DocStringExtensions
import DocStringExtensions: SIGNATURES, TYPEDSIGNATURES, DOCSTRING,
FIELDS, TYPEDFIELDS
DocStringExtensions.@template TYPES =
"""
Fields:
$(TYPEDFIELDS)
---
$(DOCSTRING)
"""
@doc """
Camera configuration.
Defines the intrinsics and extrinsics of an ideal pinhole camera.
""" CameraConfig
@kwdef struct CameraConfig
"""Pose (position and orientation) of the camera eye."""
cameraEyePose::Pose
intrinsics::CameraIntrinsics
end
becomes this
MethodError: no method matching kwarg_decl(::Method, ::Type{DocStringExtensions.var"#methodgroups##kw"})
Closest candidates are:
kwarg_decl(::Method) at methodshow.jl:77
Stacktrace:
[1] keywords(::Function, ::Method) at /home/travis/.julia/packages/DocStringExtensions/DWN8v/src/utilities.jl:302
[2] printmethod(::Base.GenericIOBuffer{Array{UInt8,1}}, ::Base.Docs.Binding, ::Function, ::Method) at /home/travis/.julia/packages/DocStringExtensions/DWN8v/src/utilities.jl:216
[3] format(::DocStringExtensions.MethodSignatures, ::Base.GenericIOBuffer{Array{UInt8,1}}, ::Base.Docs.DocStr) at /home/travis/.julia/packages/DocStringExtensions/DWN8v/src/abbreviations.jl:328
[4] formatdoc(::Base.GenericIOBuffer{Array{UInt8,1}}, ::Base.Docs.DocStr, ::DocStringExtensions.MethodSignatures) at /home/travis/.julia/packages/DocStringExtensions/DWN8v/src/abbreviations.jl:25
[5] formatdoc(::Base.Docs.DocStr) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.4/REPL/src/docview.jl:60
[6] parsedoc(::Base.Docs.DocStr) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.4/REPL/src/docview.jl:68
[7] top-level scope at /home/travis/build/JuliaDocs/Documenter.jl/test/htmlwriter.jl:160
Probably caused by JuliaLang/julia#33118
Hi, it seems that DocStringExtensions must be used in the project code.
Conceptually, this seems to be a bit weird, as I would expect it to work along with Documenter.jl
when used in docs/make.jl .
Would this be possible ?
Jürgen
Is it possible to create a new Abbreviation
type in a separate package? After implementing a format
method I only see the proper print out when I run the docstring through Docs.formatdoc
. It doesn't seem to process it for the actual docstring (i.e., @doc
) or in documenter markdown.
Hi,
documenting functions with more the one type parameter with TYPEDSIGNATURES leads to UnionAll error.
Here is the MWE:
module XDoc
using DocStringExtensions
"""
$(SIGNATURES)
Function with two type parameters.
"""
function foo(u::Tu, v::Tv) where{Tu,Tv}
println("Tu: $(Tu), v:$(Tv)")
nothing
end
"""
$(TYPEDSIGNATURES)
Another function with two type parameters.
"""
function bar(u::Tu, v::Tv) where{Tu,Tv}
println("Tu: $(Tu), v:$(Tv)")
nothing
end
end
julia> include("XDoc.jl")
help?> XDoc.bar
ERROR: type UnionAll has no field a
Stacktrace:
[1] getproperty(::Type, ::Symbol) at ./Base.jl:15
[2] printmethod(::Base.GenericIOBuffer{Array{UInt8,1}}, ::Base.Docs.Binding, ::Function, ::Method, ::Type) at /home/fuhrmann/.julia/packages/DocStringExtensions/BEyNH/src/utilities.jl:250
[3] format(::DocStringExtensions.TypedMethodSignatures, ::Base.GenericIOBuffer{Array{UInt8,1}}, ::Base.Docs.DocStr) at /home/fuhrmann/.julia/packages/DocStringExtensions/BEyNH/src/abbreviations.jl:378
[4] formatdoc(::Base.GenericIOBuffer{Array{UInt8,1}}, ::Base.Docs.DocStr, ::DocStringExtensions.TypedMethodSignatures) at /home/fuhrmann/.julia/packages/DocStringExtensions/BEyNH/src/abbreviations.jl:25
[5] formatdoc(::Base.Docs.DocStr) at /home/abuild/rpmbuild/BUILD/julia-1.2.0/usr/share/julia/stdlib/v1.2/REPL/src/docview.jl:60
[6] parsedoc(::Base.Docs.DocStr) at /home/abuild/rpmbuild/BUILD/julia-1.2.0/usr/share/julia/stdlib/v1.2/REPL/src/docview.jl:68
[7] iterate at ./generator.jl:47 [inlined]
[8] _collect(::Array{Base.Docs.DocStr,1}, ::Base.Generator{Array{Base.Docs.DocStr,1},typeof(Base.Docs.parsedoc)}, ::Base.EltypeUnknown, ::Base.HasShape{1}) at ./array.jl:619
[9] collect_similar at ./array.jl:548 [inlined]
[10] map at ./abstractarray.jl:2073 [inlined]
[11] doc(::Base.Docs.Binding, ::Type) at /home/abuild/rpmbuild/BUILD/julia-1.2.0/usr/share/julia/stdlib/v1.2/REPL/src/docview.jl:117
[12] doc(::Base.Docs.Binding) at /home/abuild/rpmbuild/BUILD/julia-1.2.0/usr/share/julia/stdlib/v1.2/REPL/src/docview.jl:85
[13] top-level scope at /home/abuild/rpmbuild/BUILD/julia-1.2.0/usr/share/julia/stdlib/v1.2/REPL/src/docview.jl:355
help?> XDoc.foo
foo(u, v)
Function with two type parameters.
The current workaround is of course to use SIGNATURES, but I like the possibility to generate as much information as possible from the code.
Jürgen
@template
doesn't seem to work when a struct is processed by a macro, and Base.@__doc__
is used in the macro.
The docs otherwise work fine. But the template is not inserted, although the format
method does actually run.
It seems like DocStringExtensions
has some test cases that use inference on "invalid" type signature.
Especially, once JuliaLang/julia#42583 is merged, Core.Compiler
will essentially ignore unbound type variables given by users, and it will change some return type signature:
I confirmed following test result on the branch:
❯ ~/julia/julia2/usr/bin/julia -e 'using Pkg; Pkg.test()'
Testing DocStringExtensions
Status `/private/var/folders/28/jpsyzp6971s99n6bd4_k6fgm0000gn/T/jl_Ojpo4j/Project.toml`
[ffbed154] DocStringExtensions v0.8.5 `~/julia/packages/DocStringExtensions`
[76f85450] LibGit2 `@stdlib/LibGit2`
[d6f4376e] Markdown `@stdlib/Markdown`
[44cfe95a] Pkg v1.8.0 `@stdlib/Pkg`
[8dfed614] Test `@stdlib/Test`
Status `/private/var/folders/28/jpsyzp6971s99n6bd4_k6fgm0000gn/T/jl_Ojpo4j/Manifest.toml`
[ffbed154] DocStringExtensions v0.8.5 `~/julia/packages/DocStringExtensions`
[0dad84c5] ArgTools v1.1.1 `@stdlib/ArgTools`
[56f22d72] Artifacts `@stdlib/Artifacts`
[2a0f44e3] Base64 `@stdlib/Base64`
[ade2ca70] Dates `@stdlib/Dates`
[f43a241f] Downloads v1.5.1 `@stdlib/Downloads`
[b77e0a4c] InteractiveUtils `@stdlib/InteractiveUtils`
[b27032c2] LibCURL v0.6.3 `@stdlib/LibCURL`
[76f85450] LibGit2 `@stdlib/LibGit2`
[8f399da3] Libdl `@stdlib/Libdl`
[56ddb016] Logging `@stdlib/Logging`
[d6f4376e] Markdown `@stdlib/Markdown`
[ca575930] NetworkOptions v1.2.0 `@stdlib/NetworkOptions`
[44cfe95a] Pkg v1.8.0 `@stdlib/Pkg`
[de0858da] Printf `@stdlib/Printf`
[3fa0cd96] REPL `@stdlib/REPL`
[9a3f8284] Random `@stdlib/Random`
[ea8e919c] SHA `@stdlib/SHA`
[9e88b42a] Serialization `@stdlib/Serialization`
[6462fe0b] Sockets `@stdlib/Sockets`
[fa267f1f] TOML v1.0.0 `@stdlib/TOML`
[a4e569a6] Tar v1.10.0 `@stdlib/Tar`
[8dfed614] Test `@stdlib/Test`
[cf7118a7] UUIDs `@stdlib/UUIDs`
[4ec0a83e] Unicode `@stdlib/Unicode`
[deac9b47] LibCURL_jll v7.73.0+4 `@stdlib/LibCURL_jll`
[29816b5a] LibSSH2_jll v1.9.1+2 `@stdlib/LibSSH2_jll`
[c8ffd9c3] MbedTLS_jll v2.24.0+2 `@stdlib/MbedTLS_jll`
[14a3606d] MozillaCACerts_jll v2020.7.22 `@stdlib/MozillaCACerts_jll`
[83775a58] Zlib_jll v1.2.12+1 `@stdlib/Zlib_jll`
[8e850ede] nghttp2_jll v1.41.0+1 `@stdlib/nghttp2_jll`
[3f19e933] p7zip_jll v16.2.1+1 `@stdlib/p7zip_jll`
Testing Running tests...
method signatures with types: Test Failed at /Users/aviatesk/julia/packages/DocStringExtensions/test/tests.jl:318
Expression: occursin(f("\nk_6(x::Array{T<:Number,1}) -> Array{T<:Number,1}\n"), str)
Evaluated: occursin("\nk_6(x::Array{T<:Number,1})->Array{T<:Number,1}\n", "\n```julia\nk_6(x::Array{T<:Number,1})->Array\n\n```\n\n")
Stacktrace:
[1] macro expansion
@ ~/julia/julia2/usr/share/julia/stdlib/v1.8/Test/src/Test.jl:460 [inlined]
[2] macro expansion
@ ~/julia/packages/DocStringExtensions/test/tests.jl:318 [inlined]
[3] macro expansion
@ ~/julia/julia2/usr/share/julia/stdlib/v1.8/Test/src/Test.jl:1321 [inlined]
[4] macro expansion
@ ~/julia/packages/DocStringExtensions/test/tests.jl:182 [inlined]
[5] macro expansion
@ ~/julia/julia2/usr/share/julia/stdlib/v1.8/Test/src/Test.jl:1321 [inlined]
[6] macro expansion
@ ~/julia/packages/DocStringExtensions/test/tests.jl:68 [inlined]
[7] macro expansion
@ ~/julia/julia2/usr/share/julia/stdlib/v1.8/Test/src/Test.jl:1321 [inlined]
[8] top-level scope
@ ~/julia/packages/DocStringExtensions/test/tests.jl:21
method signatures with types: Test Failed at /Users/aviatesk/julia/packages/DocStringExtensions/test/tests.jl:329
Expression: occursin("\nk_7(x::Union{Nothing, T<:Integer}) -> Union{Nothing, Integer}\n", str)
Evaluated: occursin("\nk_7(x::Union{Nothing, T<:Integer}) -> Union{Nothing, Integer}\n", "\n```julia\nk_7(x::Union{Nothing, T<:Integer}) -> Union{Nothing, T} where T<:Integer\nk_7(x::Union{Nothing, T<:Integer}, y::T<:Integer) -> Any\n\n```\n\n")
Stacktrace:
[1] macro expansion
@ ~/julia/julia2/usr/share/julia/stdlib/v1.8/Test/src/Test.jl:460 [inlined]
[2] macro expansion
@ ~/julia/packages/DocStringExtensions/test/tests.jl:329 [inlined]
[3] macro expansion
@ ~/julia/julia2/usr/share/julia/stdlib/v1.8/Test/src/Test.jl:1321 [inlined]
[4] macro expansion
@ ~/julia/packages/DocStringExtensions/test/tests.jl:182 [inlined]
[5] macro expansion
@ ~/julia/julia2/usr/share/julia/stdlib/v1.8/Test/src/Test.jl:1321 [inlined]
[6] macro expansion
@ ~/julia/packages/DocStringExtensions/test/tests.jl:68 [inlined]
[7] macro expansion
@ ~/julia/julia2/usr/share/julia/stdlib/v1.8/Test/src/Test.jl:1321 [inlined]
[8] top-level scope
@ ~/julia/packages/DocStringExtensions/test/tests.jl:21
method signatures with types: Test Failed at /Users/aviatesk/julia/packages/DocStringExtensions/test/tests.jl:330
Expression: occursin("\nk_7(x::Union{Nothing, T<:Integer}, y::T<:Integer) -> Union{Nothing, T<:Integer}\n", str)
Evaluated: occursin("\nk_7(x::Union{Nothing, T<:Integer}, y::T<:Integer) -> Union{Nothing, T<:Integer}\n", "\n```julia\nk_7(x::Union{Nothing, T<:Integer}) -> Union{Nothing, T} where T<:Integer\nk_7(x::Union{Nothing, T<:Integer}, y::T<:Integer) -> Any\n\n```\n\n")
Stacktrace:
[1] macro expansion
@ ~/julia/julia2/usr/share/julia/stdlib/v1.8/Test/src/Test.jl:460 [inlined]
[2] macro expansion
@ ~/julia/packages/DocStringExtensions/test/tests.jl:330 [inlined]
[3] macro expansion
@ ~/julia/julia2/usr/share/julia/stdlib/v1.8/Test/src/Test.jl:1321 [inlined]
[4] macro expansion
@ ~/julia/packages/DocStringExtensions/test/tests.jl:182 [inlined]
[5] macro expansion
@ ~/julia/julia2/usr/share/julia/stdlib/v1.8/Test/src/Test.jl:1321 [inlined]
[6] macro expansion
@ ~/julia/packages/DocStringExtensions/test/tests.jl:68 [inlined]
[7] macro expansion
@ ~/julia/julia2/usr/share/julia/stdlib/v1.8/Test/src/Test.jl:1321 [inlined]
[8] top-level scope
@ ~/julia/packages/DocStringExtensions/test/tests.jl:21
Test Summary: | Pass Fail Broken Total
DocStringExtensions | 163 3 3 169
Base assumptions | 10 10
format | 85 3 3 91
imports & exports | 3 3
type fields | 10 10
method lists | 3 3
method signatures | 16 16
method signatures with types | 44 3 3 50
function names | 1 1
type definitions | 5 5
README/LICENSE | 2 2
templates | 15 15
utilities | 53 53
ERROR: LoadError: Some tests did not pass: 163 passed, 3 failed, 0 errored, 3 broken.
in expression starting at /Users/aviatesk/julia/packages/DocStringExtensions/test/tests.jl:20
in expression starting at /Users/aviatesk/julia/packages/DocStringExtensions/test/runtests.jl:6
ERROR: Package DocStringExtensions errored during testing
Stacktrace:
[1] pkgerror(msg::String)
@ Pkg.Types ~/julia/julia2/usr/share/julia/stdlib/v1.8/Pkg/src/Types.jl:67
[2] test(ctx::Pkg.Types.Context, pkgs::Vector{Pkg.Types.PackageSpec}; coverage::Bool, julia_args::Cmd, test_args::Cmd, test_fn::Nothing, force_latest_compatible_version::Bool, allow_earlier_backwards_compatible_versions::Bool, allow_reresolve::Bool)
@ Pkg.Operations ~/julia/julia2/usr/share/julia/stdlib/v1.8/Pkg/src/Operations.jl:1694
[3] test(ctx::Pkg.Types.Context, pkgs::Vector{Pkg.Types.PackageSpec}; coverage::Bool, test_fn::Nothing, julia_args::Cmd, test_args::Cmd, force_latest_compatible_version::Bool, allow_earlier_backwards_compatible_versions::Bool, allow_reresolve::Bool, kwargs::Base.Pairs{Symbol, Base.TTY, Tuple{Symbol}, NamedTuple{(:io,), Tuple{Base.TTY}}})
@ Pkg.API ~/julia/julia2/usr/share/julia/stdlib/v1.8/Pkg/src/API.jl:427
[4] test(pkgs::Vector{Pkg.Types.PackageSpec}; io::Base.TTY, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ Pkg.API ~/julia/julia2/usr/share/julia/stdlib/v1.8/Pkg/src/API.jl:155
[5] test(pkgs::Vector{Pkg.Types.PackageSpec})
@ Pkg.API ~/julia/julia2/usr/share/julia/stdlib/v1.8/Pkg/src/API.jl:145
[6] test(; name::Nothing, uuid::Nothing, version::Nothing, url::Nothing, rev::Nothing, path::Nothing, mode::Pkg.Types.PackageMode, subdir::Nothing, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ Pkg.API ~/julia/julia2/usr/share/julia/stdlib/v1.8/Pkg/src/API.jl:170
[7] test()
@ Pkg.API ~/julia/julia2/usr/share/julia/stdlib/v1.8/Pkg/src/API.jl:164
[8] top-level scope
@ none:1
I suggest modifying the inference-related utilities so that we pass "valid" type signature to Base.return_types
, i.e. make sure not to include unbound TypeVar
s in typesig
at:
DocStringExtensions.jl/src/utilities.jl
Line 307 in 4007f63
using DocStringExtensions
"""
$(TYPEDSIGNATURES)
"""
function func(a::Integer, b::Integer = a; c::Integer = b)::Integer
a + b + c
end
@doc func
gives
func(a::Integer) -> Integer
func(a::Integer, b::Integer; c) -> Integer
TYPEDSIGNATURES
returns a simplified representation of method signatures, which, however, doesn't show the types and default values of keyword arguments. Is there a convenient way to also include them in the docstring?
The expected result is
func(a::Integer, b::Integer = a; c::Integer = b) -> Integer
This seems like a great package! One thing that's really missing is an example of how to use each and every functionality. Ideally, this would be a single page with two columns. The left would be the function definitions and the right would be the rendered help text.
More specifically, I'm currently struggling to find out how to use the FIELDS variable effectively to document the arguments to a functoin without me having to duplicate the names of all of the variables (single source of truth!!!). Let's say I have this function:
function calculate_retirement_monthly_savings(startingAmount::Number, # How much money you have now,
yearsTillDie::Number, #How many years you have to live
currentYearlyExpenses, #What you spend now (assuming you want the same quality of life when you retire
yearlyInflation::AbstractFloat, #A number slightly greater than 1 specifying buyingPowerAYearAgo/buyingPowerNow for a given amount of money.)
It would be great if those comments could make it to an argument list, with the types, but without having to duplicate (and possibly cause inconsistencies) the variable names. Is that possible with the existing pacakge? I don't currently know because I can't find examples of how to use the FIELDS variable effectively
I am working on a package where the user defines custom objects, and methods for them. I would like to document things about these methods in the generic functions. As an MWE, consider
module Foo
using DocStringExtensions
"""
$SIGNATURES
You should define `do_stuff(model, θ)` models, where `θ` are the parameters.
It should return an `<:AbstractVector{<: Real}`.
"""
function do_stuff end
end
Then the $SIGNATURES
part will be empty.
Proposed solution: for DRY, it would be great to have a DocStringExtensions.Abbreviation
, eg FUNCTIONNAME
, that would just expand to do_stuff
above, so I could use something like
"""
$FUNCTIONNAME(model, θ)
You should define methods for models, where `θ` are the parameters.
It should return an `<:AbstractVector{<: Real}`.
"""
function do_stuff end
The CI for DocStringExtensions.jl
is failing on Julia nightly.
See for example: #94
Example Travis CI job that is failing on Julia nightly: https://travis-ci.org/github/JuliaDocs/DocStringExtensions.jl/jobs/714152854
The idea is to have a macro, let us say, INTERNAL, such that a message warning the user that the function is internal is shown instead of the actual help entry, and the help entry gets hidden inside an "Extended help" section.
That is, that some like this:
INTERNAL"""
f(x)
This function always returns 1
# Example
example of use of f(x)
"""
f(x) = 1
gets parsed as:
"""
f(x)
**Internal function or structure - interface may change.**
# Extended help
This function always returns 1
# Example
example of use f(x)
"""
Such that when the user types ? f
, he/she will get:
help?> f
search: f fd for fma fld fld1 fill fdio frexp foldr foldl flush floor float first fill! fetch fldmod filter falses
f(x)
Internal function or structure - interface may change.
────────────────────────────────────────────────
Extended help is available with `??`
Ps: I tried to implement this myself, but without a proper interaction with Documenter
it does not really help much, and maybe others have the right expertise to do that (if they find the idea interesting, anyway). I have been using this pattern, by hand, in some packages, and it solves the problem of documenting inner functions without introducing possible confusions for the users.
For example, DocStringExtensions
produces the signature
iterate(ivp; solver, opts...)
for the following function definition
function iterate{S<:AbstractSolver}(ivp::IVP;
solver::Type{S} = RKIntegratorAdaptive{:rk45},
opts...)
In some cases this might be enough, but it would be helpful to be able to generate an output including the default value for the keyword arguments like this
iterate(ivp; solver=RKIntegratorAdaptive{:rk45}, opts...)
Possibly with a switch to turn this behavior on or off.
maybe I'm using it wrong, but
module Foo
@template MODULES = Foo
end
resultes in
ERROR: LoadError: KeyError: key :MODULES not found
This is an MWE for an issue originally reported in JuliaDocs/Documenter.jl#1296:
julia> using DocStringExtensions
julia> abstract type Component end
julia> struct System end
julia> """
$(TYPEDSIGNATURES)
...
"""
function get_components(
::Type{T},
sys::System,
filter_func::Union{Nothing, Function} = nothing,
) where {T <: Component}
# TODO: Verify that return type annotation is not required
#return IS.get_components(T, sys.data, filter_func)
end
get_components
help?> get_components
search: get_components
ERROR: type UnionAll has no field a
Stacktrace:
[1] getproperty(::Type{T} where T, ::Symbol) at ./Base.jl:28
[2] format(::DocStringExtensions.TypedMethodSignatures, ::Base.GenericIOBuffer{Array{UInt8,1}}, ::Base.Docs.DocStr) at /home/mortenpi/.julia/packages/DocStringExtensions/BEyNH/src/abbreviations.jl:386
[3] formatdoc(::Base.GenericIOBuffer{Array{UInt8,1}}, ::Base.Docs.DocStr, ::DocStringExtensions.TypedMethodSignatures) at /home/mortenpi/.julia/packages/DocStringExtensions/BEyNH/src/abbreviations.jl:25
[4] formatdoc(::Base.Docs.DocStr) at /home/mortenpi/Julia/julia-1.4/usr/share/julia/stdlib/v1.4/REPL/src/docview.jl:60
[5] parsedoc(::Base.Docs.DocStr) at /home/mortenpi/Julia/julia-1.4/usr/share/julia/stdlib/v1.4/REPL/src/docview.jl:68
[6] iterate at ./generator.jl:47 [inlined]
[7] _collect(::Array{Base.Docs.DocStr,1}, ::Base.Generator{Array{Base.Docs.DocStr,1},typeof(Base.Docs.parsedoc)}, ::Base.EltypeUnknown, ::Base.HasShape{1}) at ./array.jl:678
[8] collect_similar at ./array.jl:607 [inlined]
[9] map at ./abstractarray.jl:2072 [inlined]
[10] doc(::Base.Docs.Binding, ::Type{T} where T) at /home/mortenpi/Julia/julia-1.4/usr/share/julia/stdlib/v1.4/REPL/src/docview.jl:117
[11] doc(::Base.Docs.Binding) at /home/mortenpi/Julia/julia-1.4/usr/share/julia/stdlib/v1.4/REPL/src/docview.jl:85
[12] top-level scope at /home/mortenpi/Julia/julia-1.4/usr/share/julia/stdlib/v1.4/REPL/src/docview.jl:287
The issue is probably in assuming that typesig
will always have a field called :a
:
DocStringExtensions.jl/src/abbreviations.jl
Lines 382 to 391 in 9075207
I find it very helpful to include $(TYPEDSIGNATURES)
at the top of my function docstring template. I'm wondering why type annotations are included in positional arguments but not keyword arguments? I would have expected/preferred to have type annotations appear in the docstring everywhere that they appear in the actual function signature. That's how it was in the initial proposal in #20, and I haven't been able to find any further discussion on the topic.
Hi, great tool, just provides what I was missing from Documenter.
I also like TYPEDSIGNATURES. Would it be possible to add also a TYPEDFIELDS macro?
Jürgen
Consider the following function in a module CGP
"""
$(TYPEDSIGNATURES)
"""
function f2(v::Vector{Int}, m::Matrix{Float64})
return sum(v) + sum(m)
end
It seems to me that the built-in alias Vector
and Matrix
are more readable. Is it possible to show the short alias instead of the original type in the documentation?
Self-contained MWE:
path, io = mktemp()
str = """
module Test
using DocStringExtensions
\"\"\"
\$(SIGNATURES)
\"\"\"
test(arguments...) = 42
end
"""
print(io, str)
close(io)
include(path)
@doc Test.test # test(arguments), not test(arguments...)
Sometimes, short functions are best documented by their full definition (and sometimes I'm just lazy). It would be nice if $(BODY)
was replaced with log(p / (1 - p))
.
""" Logistic regression, $(BODY) """
logit(p) = log(p / (1 - p))
FIELDS is great! but the existing white space wastes a lot of screen real estate.
what would you guys think of putting the docstring on the same line as the fieldname with colon as a separator?
so instead of this:
julia> using Gadfly
help?> Theme
search: Theme
• default_color
If the color aesthetic is not mapped to anything, this is the color that is used.
(Color)
• point_size
Size of points in the point, boxplot, and beeswarm geometries. (Measure)
• point_size_min
Minimum size of points in the point geometry. (Measure)
• point_size_max
Maximum size of points in the point geometry. (Measure)
• point_shapes
Shapes of points in the point geometry. (Function in circle, square, diamond, cross,
xcross, utriangle, dtriangle, star1, star2, hexagon, octagon, hline, vline)
• line_width
Width of lines in the line geometry. (Measure)
something like this:
julia> using Gadfly
help?> Theme
search: Theme
• default_color: If the color aesthetic is not mapped to anything, this is the color that is
used (Color)
• point_size: Size of points in the point, boxplot, and beeswarm geometries. (Measure)
• point_size_min: Minimum size of points in the point geometry. (Measure)
• point_size_max: Maximum size of points in the point geometry. (Measure)
• point_shapes: Shapes of points in the point geometry. (Function in circle, square,
diamond, cross, xcross, utriangle, dtriangle, star1, star2, hexagon, octagon, hline, vline)
• line_width: Width of lines in the line geometry. (Measure)
or even this:
julia> using Gadfly
help?> Theme
search: Theme
• default_color: If the color aesthetic is not mapped to anything, this is the color that is
used (Color)
• point_size: Size of points in the point, boxplot, and beeswarm geometries. (Measure)
• point_size_min: Minimum size of points in the point geometry. (Measure)
• point_size_max: Maximum size of points in the point geometry. (Measure)
• point_shapes: Shapes of points in the point geometry. (Function in circle, square,
diamond, cross, xcross, utriangle, dtriangle, star1, star2, hexagon, octagon, hline, vline)
• line_width: Width of lines in the line geometry. (Measure)
note that these examples rely on GiovineItalia/Gadfly.jl#1173, which is not merged yet.
The manual says:
This package provides a collection of useful extensions for Julia's built-in docsystem. These are features that are still regarded as "experimental" and not yet mature enough to be considered for inclusion in Base, or that have sufficiently niche use cases that including them with the default Julia installation is not seen as valuable enough at this time.
What would be needed to be considered mature enough for upstreaming this package to Base?
I tried to use DocStringExtensions.jl
with the package Krylov.jl
but I encountered some problems. When I build the docs, the signature of only two random Krylov solvers is generated. Do you have an idea where the problem comes from?
JuliaSmoothOptimizers/Krylov.jl#208
Consider the following two functions in module CGP
.
"""
$(TYPEDSIGNATURES)
"""
function fun1(x::AbstractVector{<:Real})
end
"""
$(TYPEDSIGNATURES)
"""
function fun2(x::AbstractVector{T}) where T<:Real
end
The following documentation is produced.
I noticed two issues.
AbstractVector
in fun2
becomes AbstractArray
again even if I am using Julia 1.6.0. (See #108)fun1
, the implicit type parameter is an ugly var"#s2"
. Is it possible to just show the original form x::AbstractVector{<:Real}
?TYPEDEF
ommits type parameters of abstract types. E.g.
using DocStringExtensions: TYPEDEF
"""
$(TYPEDEF)
"""
abstract type MyAbstractType{T} end
Will result in the following (REPL) documentation:
help?> MyAbstractType
abstract type MyAbstractType
There are a few doctest failures, probably due to printing changes between Julia versions. Also, doctest failures do not currently fail the documentation build.
┌ Error: doctest failure in ~/work/DocStringExtensions.jl/DocStringExtensions.jl/src/utilities.jl:221-245
│
│ ```jldoctest; setup = :(using DocStringExtensions)
│ julia> DocStringExtensions.find_tuples(Tuple{String,Number,Int})
│ 1-element Array{DataType,1}:
│ Tuple{String,Number,Int64}
│
│ julia> DocStringExtensions.find_tuples(Tuple{T} where T <: Integer)
│ 1-element Array{DataType,1}:
│ Tuple{T<:Integer}
│
│ julia> s = Union{
│ Tuple{Int64},
│ Tuple{U},
│ Tuple{T},
│ Tuple{Int64,T},
│ Tuple{Int64,T,U}
│ } where U where T;
│
│ julia> DocStringExtensions.find_tuples(s)
│ 5-element Array{DataType,1}:
│ Tuple{Int64}
│ Tuple{U}
│ Tuple{T}
│ Tuple{Int64,T}
│ Tuple{Int64,T,U}
│ ```
│
│ Subexpression:
│
│ DocStringExtensions.find_tuples(Tuple{String,Number,Int})
│
│ Evaluated output:
│
│ 1-element Vector{DataType}:
│ Tuple{String, Number, Int64}
│
│ Expected output:
│
│ 1-element Array{DataType,1}:
│ Tuple{String,Number,Int64}
│
│ Tuple{T<:Integer}
└ @ Documenter.DocTests ~/.julia/packages/Documenter/oBZFM/src/DocTests.jl:385
┌ Error: doctest failure in ~/work/DocStringExtensions.jl/DocStringExtensions.jl/src/utilities.jl:221-245
│
│ ```jldoctest; setup = :(using DocStringExtensions)
│ julia> DocStringExtensions.find_tuples(Tuple{String,Number,Int})
│ 1-element Array{DataType,1}:
│ Tuple{String,Number,Int64}
│
│ julia> DocStringExtensions.find_tuples(Tuple{T} where T <: Integer)
│ 1-element Array{DataType,1}:
│ Tuple{T<:Integer}
│
│ julia> s = Union{
│ Tuple{Int64},
│ Tuple{U},
│ Tuple{T},
│ Tuple{Int64,T},
│ Tuple{Int64,T,U}
│ } where U where T;
│
│ julia> DocStringExtensions.find_tuples(s)
│ 5-element Array{DataType,1}:
│ Tuple{Int64}
│ Tuple{U}
│ Tuple{T}
│ Tuple{Int64,T}
│ Tuple{Int64,T,U}
│ ```
│
│ Subexpression:
│
│ DocStringExtensions.find_tuples(s)
│
│ Evaluated output:
│
│ 5-element Vector{DataType}:
│ Tuple{Int64}
│ Tuple{U}
│ Tuple{T}
│ Tuple{Int64, T}
│ Tuple{Int64, T, U}
│
│ Expected output:
│
│ 5-element Array{DataType,1}:
│ Tuple{Int64}
│ Tuple{U}
│ Tuple{T}
│ Tuple{Int64,T}
│ Tuple{Int64,T,U}
│
│ diff =
│ 5-element Array{DataType,1}:
│ Vector{DataType}:
│ Tuple{Int64}
│ Tuple{U}
│ Tuple{T}
│ Tuple{Int64,T}
│ Tuple{Int64,T,U}Tuple{Int64, T}
│ Tuple{Int64, T, U}
└ @ Documenter.DocTests ~/.julia/packages/Documenter/oBZFM/src/DocTests.jl:385
Perhaps the doc writer should be able to decide whether a generated block needs a heading or not, instead of it being forced to be there? It would allow more freedom in how the abbreviations can be integrated into docstrings.
Most relevant probably for signatures. I think according to the manual the idiomatic way to write docstrings is to have the signature code blocks as the first thing in the docstring, and there we definitely don't need the heading (visible in Documenter's doc, e.g. Documenter.DocChecks.doctest
).
But could also be relevant for others, say if you want to add a sentence or two before the list. It should probably be consistent across all abbreviations as well. I would propose changing the semantics so that the abbreviation would generate only the list/block/etc. and would not decorate it.
Forcing the users write something like this
# Fields
$(FIELDS)
for the common case should probably not be an issue.
Similar to #32.
julia> using DocStringExtensions
julia> """
$(SIGNATURES)
"""
f(x::T; y = x) where {T} = x * y
f
help?> f
results in
ERROR: type UnionAll has no field parameters
Stacktrace:
[1] tuple_type_cons(::Type{Array{Any,1}}, ::Type{Tuple{#f,T} where T}) at ./essentials.jl:81
[2] keywords(::Function, ::Method) at /Users/twan/code/julia/RigidBodyDynamics/v0.6/DocStringExtensions/src/utilities.jl:244
[3] printmethod(::Base.AbstractIOBuffer{Array{UInt8,1}}, ::Base.Docs.Binding, ::Function, ::Method) at /Users/twan/code/julia/RigidBodyDynamics/v0.6/DocStringExtensions/src/utilities.jl:213
[4] format(::DocStringExtensions.MethodSignatures, ::Base.AbstractIOBuffer{Array{UInt8,1}}, ::Base.Docs.DocStr) at /Users/twan/code/julia/RigidBodyDynamics/v0.6/DocStringExtensions/src/abbreviations.jl:299
[5] formatdoc(::Base.AbstractIOBuffer{Array{UInt8,1}}, ::Base.Docs.DocStr, ::DocStringExtensions.MethodSignatures) at /Users/twan/code/julia/RigidBodyDynamics/v0.6/DocStringExtensions/src/abbreviations.jl:25
[6] formatdoc(::Base.Docs.DocStr) at ./docs/Docs.jl:178
[7] parsedoc(::Base.Docs.DocStr) at ./docs/Docs.jl:186
[8] _collect(::Array{Base.Docs.DocStr,1}, ::Base.Generator{Array{Base.Docs.DocStr,1},Base.Docs.#parsedoc}, ::Base.EltypeUnknown, ::Base.HasShape) at ./array.jl:454
[9] doc(::Base.Docs.Binding, ::Type{T} where T) at ./docs/Docs.jl:312
[10] doc(::Base.Docs.Binding) at ./docs/Docs.jl:280
julia> using DocStringExtensions
julia> """
$(SIGNATURES)
This function destructures!
"""
function f((x, y))
x + y
end
f
julia> @doc f
f(#temp#)
This function destructures!
julia> VERSION
v"1.0.1-pre.0"
it would be nice to have f((x, y))
.
It would be very convenient to have a docstring "template" which can be made to apply to all functions in a module. Eg: one could define at the start of a module that each docstring will present function names with type signatures, default argument values and a url to the function definition.
Also part of the template could be a slot (abbreviation?) where locally defined docstrings would be filled in. Eg: When one describes some detail specific to a function, that description could get filled in between the type signature and the url, if the programmer so chooses.
Could you please publish a new tag? I can't release a new version of my package until this is done, and I'm sure there are others in my situation. If you're OK with giving me push access (even temporarily) I can do it myself too.
Given the following MWE:
using DocStringExtensions
@template DEFAULT = """
The `DEFAULT` template.
$(DOCSTRING)
"""
@template TYPES = """
The `TYPES` template.
$(DOCSTRING)
$(TYPEDFIELDS)
"""
"Foo's docstring"
struct Foo{S}
"bar's docstring"
bar::S
end
println(@doc(Foo))
I was expecting the output to be
The `TYPES` template.
Foo's docstring, with fields
* `bar::Any`
bar's docstring
Instead, it is
The `DEFAULT` template.
Foo's docstring, without any fields
I'm expecting this to have to do with how applicable templates are determined which checks for a DataType
, whereas Foo
is a UnionAll
. Given my simple use case, it seems like this could be a simple extension to that function (although I'm not sure what it'd look like). However, I can imagine there are some subtleties at play here given that we're talking about UnionAll
.
The bug is present on the latest registered version of DocStringExtensions, as well as the latest DocStringExtensions master.
(@v1.6) pkg> add DocStringExtensions
Installing known registries into `~/.julia`
[ Info: LEGAL NOTICE: package operations send anonymous data about your system to https://pkg.julialang.org (your current package server), including the operating system and Julia versions you are using, and a random client UUID. Running `Pkg.telemetryinfo()` will show exactly what data is sent. See https://julialang.org/legal/data/ for more details about what this data is used for, how long it is retained, and how to opt out of sending it.
######################################################################## 100.0%
Added registry `General` to `~/.julia/registries/General`
Resolving package versions...
Installed DocStringExtensions ─ v0.8.2
Updating `~/.julia/environments/v1.6/Project.toml`
[ffbed154] + DocStringExtensions v0.8.2
Updating `~/.julia/environments/v1.6/Manifest.toml`
[ffbed154] + DocStringExtensions v0.8.2
[2a0f44e3] + Base64
[ade2ca70] + Dates
[8ba89e20] + Distributed
[b77e0a4c] + InteractiveUtils
[76f85450] + LibGit2
[8f399da3] + Libdl
[56ddb016] + Logging
[d6f4376e] + Markdown
[44cfe95a] + Pkg
[de0858da] + Printf
[3fa0cd96] + REPL
[9a3f8284] + Random
[ea8e919c] + SHA
[9e88b42a] + Serialization
[6462fe0b] + Sockets
[8dfed614] + Test
[cf7118a7] + UUIDs
[4ec0a83e] + Unicode
julia> import DocStringExtensions
[ Info: Precompiling DocStringExtensions [ffbed154-4ef7-542d-bbb7-c09d3a79fcae]
julia> """
$(DocStringExtensions.TYPEDSIGNATURES)
"""
function foo(x)
return nothing
end
foo
help?> foo
search: foo floor pointer_from_objref OverflowError RoundFromZero unsafe_copyto! functionloc StackOverflowError @functionloc OutOfMemoryError UndefKeywordError
ERROR: ArgumentError: invalid index: nothing of type Nothing
Stacktrace:
[1] to_index(i::Nothing)
@ Base ./indices.jl:297
[2] to_index(A::Vector{DataType}, i::Nothing)
@ Base ./indices.jl:274
[3] to_indices(A::Vector{DataType}, inds::Tuple{Base.OneTo{Int64}}, I::Tuple{Nothing})
@ Base ./indices.jl:329
[4] to_indices(A::Vector{DataType}, I::Tuple{Nothing})
@ Base ./indices.jl:322
[5] getindex(A::Vector{DataType}, I::Nothing)
@ Base ./abstractarray.jl:1119
[6] format(#unused#::DocStringExtensions.TypedMethodSignatures, buf::IOBuffer, doc::Base.Docs.DocStr)
@ DocStringExtensions ~/.julia/packages/DocStringExtensions/ojJPU/src/abbreviations.jl:389
[7] formatdoc(buf::IOBuffer, doc::Base.Docs.DocStr, part::DocStringExtensions.TypedMethodSignatures)
@ DocStringExtensions ~/.julia/packages/DocStringExtensions/ojJPU/src/abbreviations.jl:25
[8] formatdoc(d::Base.Docs.DocStr)
@ REPL ~/dev/repos/aluthge-forks/julia/usr/share/julia/stdlib/v1.6/REPL/src/docview.jl:85
[9] parsedoc(d::Base.Docs.DocStr)
@ REPL ~/dev/repos/aluthge-forks/julia/usr/share/julia/stdlib/v1.6/REPL/src/docview.jl:93
[10] iterate
@ ./generator.jl:47 [inlined]
[11] _collect(c::Vector{Base.Docs.DocStr}, itr::Base.Generator{Vector{Base.Docs.DocStr},typeof(Base.Docs.parsedoc)}, #unused#::Base.EltypeUnknown, isz::Base.HasShape{1})
@ Base ./array.jl:699
[12] collect_similar
@ ./array.jl:628 [inlined]
[13] map
@ ./abstractarray.jl:2225 [inlined]
[14] doc(binding::Base.Docs.Binding, sig::Type)
@ REPL ~/dev/repos/aluthge-forks/julia/usr/share/julia/stdlib/v1.6/REPL/src/docview.jl:187
[15] doc(binding::Base.Docs.Binding)
@ REPL ~/dev/repos/aluthge-forks/julia/usr/share/julia/stdlib/v1.6/REPL/src/docview.jl:155
[16] top-level scope
@ ~/dev/repos/aluthge-forks/julia/usr/share/julia/stdlib/v1.6/REPL/src/docview.jl:372
To edit a specific method, type the corresponding number into the REPL and press Ctrl+Q
julia> import InteractiveUtils
julia> InteractiveUtils.versioninfo()
Julia Version 1.6.0-DEV.569
Commit 84ef118f06 (2020-08-01 18:56 UTC)
Platform Info:
OS: macOS (x86_64-apple-darwin19.6.0)
CPU: Intel(R) Core(TM) i5-4278U CPU @ 2.60GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-9.0.1 (ORCJIT, haswell)
(@v1.6) pkg> add DocStringExtensions#master
Installing known registries into `~/.julia`
[ Info: LEGAL NOTICE: package operations send anonymous data about your system to https://pkg.julialang.org (your current package server), including the operating system and Julia versions you are using, and a random client UUID. Running `Pkg.telemetryinfo()` will show exactly what data is sent. See https://julialang.org/legal/data/ for more details about what this data is used for, how long it is retained, and how to opt out of sending it.
######################################################################## 100.0%
Added registry `General` to `~/.julia/registries/General`
Cloning git-repo `https://github.com/JuliaDocs/DocStringExtensions.jl.git`
Updating git-repo `https://github.com/JuliaDocs/DocStringExtensions.jl.git`
Updating registry at `~/.julia/registries/General`
Resolving package versions...
Updating `~/.julia/environments/v1.6/Project.toml`
[ffbed154] + DocStringExtensions v0.8.2 `https://github.com/JuliaDocs/DocStringExtensions.jl.git#master`
Updating `~/.julia/environments/v1.6/Manifest.toml`
[ffbed154] + DocStringExtensions v0.8.2 `https://github.com/JuliaDocs/DocStringExtensions.jl.git#master`
[2a0f44e3] + Base64
[ade2ca70] + Dates
[8ba89e20] + Distributed
[b77e0a4c] + InteractiveUtils
[76f85450] + LibGit2
[8f399da3] + Libdl
[56ddb016] + Logging
[d6f4376e] + Markdown
[44cfe95a] + Pkg
[de0858da] + Printf
[3fa0cd96] + REPL
[9a3f8284] + Random
[ea8e919c] + SHA
[9e88b42a] + Serialization
[6462fe0b] + Sockets
[8dfed614] + Test
[cf7118a7] + UUIDs
[4ec0a83e] + Unicode
julia> import DocStringExtensions
[ Info: Precompiling DocStringExtensions [ffbed154-4ef7-542d-bbb7-c09d3a79fcae]
julia> """
$(DocStringExtensions.TYPEDSIGNATURES)
"""
function foo(x)
return nothing
end
foo
help?> foo
search: foo floor pointer_from_objref OverflowError RoundFromZero unsafe_copyto! functionloc StackOverflowError @functionloc OutOfMemoryError UndefKeywordError
ERROR: ArgumentError: invalid index: nothing of type Nothing
Stacktrace:
[1] to_index(i::Nothing)
@ Base ./indices.jl:297
[2] to_index(A::Vector{DataType}, i::Nothing)
@ Base ./indices.jl:274
[3] to_indices(A::Vector{DataType}, inds::Tuple{Base.OneTo{Int64}}, I::Tuple{Nothing})
@ Base ./indices.jl:329
[4] to_indices(A::Vector{DataType}, I::Tuple{Nothing})
@ Base ./indices.jl:322
[5] getindex(A::Vector{DataType}, I::Nothing)
@ Base ./abstractarray.jl:1119
[6] format(#unused#::DocStringExtensions.TypedMethodSignatures, buf::IOBuffer, doc::Base.Docs.DocStr)
@ DocStringExtensions ~/.julia/packages/DocStringExtensions/ojJPU/src/abbreviations.jl:389
[7] formatdoc(buf::IOBuffer, doc::Base.Docs.DocStr, part::DocStringExtensions.TypedMethodSignatures)
@ DocStringExtensions ~/.julia/packages/DocStringExtensions/ojJPU/src/abbreviations.jl:25
[8] formatdoc(d::Base.Docs.DocStr)
@ REPL ~/dev/repos/aluthge-forks/julia/usr/share/julia/stdlib/v1.6/REPL/src/docview.jl:85
[9] parsedoc(d::Base.Docs.DocStr)
@ REPL ~/dev/repos/aluthge-forks/julia/usr/share/julia/stdlib/v1.6/REPL/src/docview.jl:93
[10] iterate
@ ./generator.jl:47 [inlined]
[11] _collect(c::Vector{Base.Docs.DocStr}, itr::Base.Generator{Vector{Base.Docs.DocStr},typeof(Base.Docs.parsedoc)}, #unused#::Base.EltypeUnknown, isz::Base.HasShape{1})
@ Base ./array.jl:699
[12] collect_similar
@ ./array.jl:628 [inlined]
[13] map
@ ./abstractarray.jl:2225 [inlined]
[14] doc(binding::Base.Docs.Binding, sig::Type)
@ REPL ~/dev/repos/aluthge-forks/julia/usr/share/julia/stdlib/v1.6/REPL/src/docview.jl:187
[15] doc(binding::Base.Docs.Binding)
@ REPL ~/dev/repos/aluthge-forks/julia/usr/share/julia/stdlib/v1.6/REPL/src/docview.jl:155
[16] top-level scope
@ ~/dev/repos/aluthge-forks/julia/usr/share/julia/stdlib/v1.6/REPL/src/docview.jl:372
To edit a specific method, type the corresponding number into the REPL and press Ctrl+Q
julia> import InteractiveUtils
julia> InteractiveUtils.versioninfo()
Julia Version 1.6.0-DEV.569
Commit 84ef118f06 (2020-08-01 18:56 UTC)
Platform Info:
OS: macOS (x86_64-apple-darwin19.6.0)
CPU: Intel(R) Core(TM) i5-4278U CPU @ 2.60GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-9.0.1 (ORCJIT, haswell)
Not sure what causes the issue, but I can see duplicate signatures when I use StridedVector{T}
or StridedMatrix{T}
in function argments. A test code:
test.jl:
module Foo
export f,g,h
using DocStringExtensions
"""
$(SIGNATURES)
"""
f(x::Vector{Int}) = x
"""
$(SIGNATURES)
"""
g(x::StridedVector) = x
"""
$(SIGNATURES)
"""
h(x::StridedVector{Int}) = x
end
julia> workspace();include("test.jl"); using Foo
help?> f
search: f fd for fma fld fft full fld1 find filt fill fft! fdio Foo frexp foldr foldl flush floor float first findn filt! fill! fetch FFTW fldmod findnz findin filter falses
f(x)
help?> g
search: g gc get gcd get! gcdx gperm gamma global golden givens getpid getkey gensym getfield gradient getindex GotoNode graphemes getipaddr gc_enable GlobalRef getsockname
g(x)
help?> h
search: h hex hton htol hist hcat hash hypot hvcat hist! HTML hist2d haskey homedir hist2d! hex2num hessfact hankelh2 hankelh1 histrange hex2bytes hessfact! hankelh2x hankelh1x
h(x)
h(x)
h(x)
Version info:
julia> versioninfo()
Julia Version 0.6.0-dev.328
Commit 03e7c79* (2016-08-20 08:15 UTC)
Platform Info:
System: Darwin (x86_64-apple-darwin15.5.0)
CPU: Intel(R) Core(TM) i5-4258U CPU @ 2.40GHz
WORD_SIZE: 64
BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Haswell)
LAPACK: libopenblas64_
LIBM: libopenlibm
LLVM: libLLVM-3.7.1 (ORCJIT, haswell)
How do you feel about dropping support for 0.4 and 0.5? Some reasons to do so:
depwarn
-free on 0.7 due to the immutable
-> struct
change. I've got https://github.com/tkoolen/docstringextensions.jl/tree/tk-fix-depwarns ready to be PR'd, but there's no Compat for struct
because it's a parser change, and the workaround is not very desirable.A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.