Skip to content

Abbreviate show(io, ::Module) #54347

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

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

Seelengrab
Copy link
Contributor

@Seelengrab Seelengrab commented May 3, 2024

For cases like

module A
    module B end
end

, A is already visible in Main once defined. As a consequence, B can be accessed through A.B without having to go through Main. This adjusts the printing of A.B, so that this is reflected.

This also makes cases like

module A
    export B

    module B
       f() = "foo"
    end
end

have f printed like B.f and not A.B.f after using A, since B is also already accessible in Main.

Seelengrab added 2 commits May 3, 2024 14:04
For cases like

```
module A
    module B end
end
```

, `A` is already visible in `Main` once defined.
As a consequence, `B` can be accessed through `A.B`
without having to go through `Main`. This adjusts
the printing of `A.B`, so that this is reflected.

This also makes cases like

```
module A
    export B

    module B end
end
```

print like `B` and not `A.B` after `using A`, since
`B` is already accessible from `Main`.
@Seelengrab
Copy link
Contributor Author

Failures are real - one consequence of this PR is that e.g. Base.Iterators is truthfully printed as just Iterators, similar for Threads, because the name is exported:

julia> Base.isexported(Base, :Iterators)
true

julia> Base.isexported(Base, :Threads)
true

It's long been convention though to prefix these with Base everywhere 🤔 Should I change the docstrings or exclude these manually?

@KristofferC
Copy link
Member

Imo, this should just not be done (and instead we should strive the other direction). Having things printed differently depending on the local context of where it is printed has caused many issues (#42329).

Also ref #29466

@Seelengrab
Copy link
Contributor Author

Seelengrab commented May 3, 2024

My usecase is consistency of show with what users can type/have access to; in the REPL this is Main, in other places it would of course be that module. I have types defined in a submodule like so:

module A
   export B

   module B
       struct C end
   end
end

Users aren't generally expected to need C directly, the default pattern of access is through B.C. Currently, this prints in the REPL as Main.A.B.C (or A.B.C if the module is obtained through a package and not defined in Main) though, which is superfluous (and quite bloaty if A is something longer). Since C is not generally used in A though, I can't just set a module context through an IOContext; there is no chain that ends up printing this as B.C:

julia> using .A

julia> println(IOContext(stdout, :module => Main), B.C())
Main.A.B.C()

julia> println(IOContext(stdout, :module => A), B.C())
Main.A.B.C()

julia> println(IOContext(stdout, :module => B), B.C())
C()

julia> println(IOContext(stdout, :module => Base), B.C())
Main.A.B.C()

julia> versioninfo()
Julia Version 1.11.0-alpha2
Commit 9dfd28ab751 (2024-03-18 20:35 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: 24 × AMD Ryzen 9 7900X 12-Core Processor
  WORD_SIZE: 64
  LLVM: libLLVM-16.0.6 (ORCJIT, znver4)
Threads: 1 default, 0 interactive, 1 GC (on 24 virtual cores)
Environment:
  JULIA_PKG_USE_CLI_GIT = true

Ideally, these would be (per module context) printed as

  • Main -> B.C() (since we have direct access to B in Main)
  • A -> B.C() (since we have direct access to B in A)
  • B -> C() (since we have direct access to C in B)
  • Base -> Main.A.B.C() (since we have no direct access and need to go through the implicit global Main module)

but as you note, that runs into trouble with too much location specific printing. Personally, I'd prefer to print things globally the same, in a way that they are as short as possible while still being copy-pastable. That's what this PR attempts.

Would it be better if this checks isvisible(module_name, parentmodule(m), active_module()) instead of Main?

Instead of hardcoding `Main` to be more special, it's better
to either retrieve a given module from an `IOContext`, or use
the currently active module for printing.
@Seelengrab
Copy link
Contributor Author

I've adjusted the code to first try to retrieve a given context module from the given IO, falling back to active_module(). I think this is the best option here.

@Seelengrab
Copy link
Contributor Author

Failures are real - seems like I missed some earlier! I'll get to them tomorrow.

@Seelengrab Seelengrab force-pushed the abbreviate_module_show branch from f484651 to d6ec22d Compare May 8, 2024 06:54
@tecosaur tecosaur added the display and printing Aesthetics and correctness of printed representations of objects. label May 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
display and printing Aesthetics and correctness of printed representations of objects.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants