Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should be able to alias full paths to modules #1781

Open
frankier opened this issue Mar 22, 2022 · 12 comments
Open

Should be able to alias full paths to modules #1781

frankier opened this issue Mar 22, 2022 · 12 comments

Comments

@frankier
Copy link
Contributor

It should be possible to alias the full paths to modules as generated by autodocs. The general reason is that this gives more flexibility for packge authors to display their public interface as they see it. The specific reason is that currently https://github.com/Roger-luo/FromFile.jl inserts modules that are essentially a private part of its implementation into documentation. It would be nice to have a way to work around this.

For an example, see https://astroautomata.com/SymbolicRegression.jl/stable/types/ . Notice the file paths in the module paths.

@mortenpi
Copy link
Member

Does FromFile.jl evaluate the definitions into a generated submodule with a convoluted name?Documenter tries to reflect things as they are, so if a binding lives in a strange submodule, Documenter reflects that. Arguably, FromFile should place the bindings into the top-level module if that is the intended public API.

That said, it might be possible to attach docstrings to different bindings somehow, as they are just stored in a special dictonary object in each module (which you can access via Docs.meta(MyModule)). That way Documenter wouldn't need to do anything special, and I think this would be preferred as then the information about the "aliasing" is stored with the docstring directly.

@nsajko
Copy link

nsajko commented Jun 12, 2024

IMO this is a serious issue, it's misrepresentation of user package API.

For example, in my package CallableExpressions.jl, I have some doc strings in the top-level module, where the names are imported from private modules. The generated documentation misleadingly mentions the names of the private modules.

The first doc string, for example, is for DynamicExpression: https://gitlab.com/nsajko/CallableExpressions.jl/-/blob/656b3e70536a7b815f49630d6aa0e4a8315964c8/src/CallableExpressions.jl#L57-62

The generated docs are titled CallableExpressions.DynamicExpressions.DynamicExpression instead of CallableExpressions.DynamicExpression.

Also affects the docs of Julia itself, resulting in breakage for users: JuliaLang/julia#54534

xref #2087?

@fredrikekre
Copy link
Member

julia> CallableExpressions.DynamicExpression === CallableExpressions.DynamicExpressions.DynamicExpression
true

@nsajko
Copy link

nsajko commented Jun 12, 2024

Yes but the doc string is not defined in DynamicExpressions. If that counts for something.

@nsajko
Copy link

nsajko commented Jun 12, 2024

Also:

julia> Base.ispublic(CallableExpressions, :DynamicExpression)
true

julia> Base.ispublic(CallableExpressions, :DynamicExpressions)
false

@fredrikekre
Copy link
Member

fredrikekre commented Jun 12, 2024

Yes but the doc string is not defined in DynamicExpressions. If that counts for something.

You attach the docstring to CallableExpressions.DynamicExpressions.DynamicExpression.

Also: [...]

Why does that matter?

@nsajko
Copy link

nsajko commented Jun 12, 2024

Why does that matter?

It matters because I want only the public API to be documented.

@goerz
Copy link
Member

goerz commented Jun 12, 2024

I sympathize with wanting to document functions under an aliased name. I have the same problem in QuantumControl: there are a lot of things defined in QuantumControlBase and re-exported in QuantumControl. Ideally, the QuantumControlBase should be more or less hidden from users. For example, I'd prefer if users used QuantumControl.ControlProblem, not QuantumControlBase.ControlProblem, even though the latter is the canonical name.

However, from Julia's perspective, each function/type has one and only one canonical fully specified name, and that's the one that Documenter shows. So basically, we'd have to tell Documenter to lie about the canonical name. I don't think there's any way to come up with an automatic way to do this. Certainly, Julia has no way to determine where the docstring for CallableExpressions.DynamicExpression was attached. It might work to define a mapping canonical path -> canonical alias for Documenter as a dict that gets passed as an argument to makedocs. Then, when Documenter renders docstrings, it would show the desired alias instead of canonical path. I'm not sure if this would be easy to implement. At first glance, it seems like it would, but one would have to be careful not to mess with the @ref-resolution, or anything like that.

@goerz
Copy link
Member

goerz commented Jun 12, 2024

By the way, how I (somewhat) get around this limitation is to have a script that generates an API overview with the "canonical aliases": https://juliaquantumcontrol.github.io/QuantumControl.jl/stable/api/quantum_control/.

That page describes the API as I'd like people to use it, but if you click on any of the actual items, you'll still see the canonical path, e.g. QuantumControl.ControlProblem or QuantumControls.Controls.evaluate, both of which have their canonical location in other packages.

@mortenpi
Copy link
Member

Certainly, Julia has no way to determine where the docstring for CallableExpressions.DynamicExpression was attached.

Actually, technically, I think we do have that metadata (module and/or file). IIRC, we use it to determine if a docstring for e.g. a Base function/type comes from Base or from a package extending that function.

@fredrikekre
Copy link
Member

You can also just document a new binding in the correct module that is const equal the "internal" one.

@tecosaur
Copy link

You can also just document a new binding in the correct module that is const equal the "internal" one.

This does seem to cause undesirable difference in printing though. Compare:

julia> module Foo
       module Internal
       struct Bar end
       end
       using .Internal
       const Bar = Internal.Bar
       export Bar
       end
Main.Foo

julia> using .Foo

julia> Bar
Main.Foo.Internal.Bar

vs.

julia> module Foo
       module Internal
       struct Bar end
       end
       using .Internal: Bar
       export Bar
       end
Main.Foo

julia> using .Foo

julia> Bar
Bar

tecosaur added a commit to JuliaLang/StyledStrings.jl that referenced this issue Sep 25, 2024
This opens the door to shuffling parts currently implemented in Base
into this stdlib without breaking any public APIs.

It would be nice to actually show the relevant Annotated* docstrings,
but unfortunately due to
JuliaDocs/Documenter.jl#1781 it's a bit
difficult to actually do so. We should re-visit this later.
tecosaur added a commit to JuliaLang/StyledStrings.jl that referenced this issue Oct 15, 2024
This opens the door to shuffling parts currently implemented in Base
into this stdlib without breaking any public APIs.

It would be nice to actually show the relevant Annotated* docstrings,
but unfortunately due to
JuliaDocs/Documenter.jl#1781 it's a bit
difficult to actually do so. We should re-visit this later.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants