Skip to content

Conversation

vtjnash
Copy link
Member

@vtjnash vtjnash commented Sep 30, 2025

Added in #58108 without valid justification: something simply being documented in the manual is never any allowable argument for making something public. Being public is confusing users, since all of the other related infrastructure is also declared private (project files, loaded_modules_array, PkgId, require, etc.). Some of those do have legit uses in reflection testing, but we don't currently have a representation for this sort of private-except-reflection in most places (other than Core.IR).

However is not allowed for packages to call Base.get_extension, since it requires accessing private implementation details of the target package to construct the arguments, and can run afoul of various implementation rules (world ages, module identity, precompile file consistency) that can lead to buggy execution.

The correct way to use this functionality is with dispatch. Loosely:

module Main
function get_extension end
end

module MainPkgExt # extension module in Main
using Other
Main.get_extension(args...) = Other.call(args...)
end

Added in #58108 without valid justification: something
simply being documented in the manual is never any allowable argument
for making something public. Being public is confusing users, since all
of the other related infrastructure is also declared private (project
files, `loaded_modules_array`, `PkgId`, `require`, etc.). Some of those
do have legit uses in reflection testing, but we don't currently have a
representation for this sort of private-except-reflection in most places
(other than `Core.IR`).

However is not allowed for packages to call `Base.get_extension`, since
it requires accessing private implementation details of the target
package to construct the arguments, and can run afoul of various
implementation rules (world ages, module identity, precompile file
consistency) that can lead to buggy execution.

The correct way to use this functionality is with dispatch. Loosely:
```julia
module Main
function get_extension end
end

module MainPkgExt # extension module in Main
using Other
Main.get_extension(args...) = Other.call(args...)
end
```
@vtjnash vtjnash requested a review from KristofferC September 30, 2025 16:08
@vtjnash vtjnash added the backport 1.12 Change should be backported to release-1.12 label Sep 30, 2025
@ericphanson
Copy link
Contributor

since it requires accessing private implementation details of the target package to construct the arguments

is this referring to the name of the extension? (surely the package's module itself is not private?)

@giordano giordano added the needs pkgeval Tests for all registered packages should be run with this change label Sep 30, 2025
@giordano
Copy link
Member

There are hundreds of packages using this already: https://juliahub.com/ui/Search?type=code&q=Base.get_extension

@KristofferC KristofferC removed the backport 1.12 Change should be backported to release-1.12 label Sep 30, 2025
@KristofferC
Copy link
Member

Docstring can be updated to avoid user mistakes.

@vtjnash
Copy link
Member Author

vtjnash commented Sep 30, 2025

That's fine. I am not proposing that we delete it, simply to communicate formally (to lint tools) that this is not an approved way to do things. There is no pkgeval required, since this annotation does not affect runtime.

@vtjnash vtjnash removed the needs pkgeval Tests for all registered packages should be run with this change label Sep 30, 2025
@vtjnash
Copy link
Member Author

vtjnash commented Sep 30, 2025

Docstring can be updated to avoid user mistakes.

Yes, I didn't not write reland or revert since this is the requested doc change.

@vtjnash vtjnash added the docs This change adds or pertains to documentation label Sep 30, 2025
Return the module for `extension` of `parent` or return `nothing` if the extension is not loaded.
Return the module for `extension` relative to `parent` or return `nothing` if the extension is not loaded.
This function is private, since the arguments to it are private implementation details.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In how far are the arguments private?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ext name is private, and the parent argument is used to extract PkgId which is internally also private

@vtjnash
Copy link
Member Author

vtjnash commented Oct 6, 2025

surely the package's module itself is not private

A module is private, other than its own name & the things it declares public internally: a module reference does not give you the public permission to do any arbitrary reflection with it (otherwise the whole public/private distinction is moot). This is a reflection function, and thus simply having the module reference does not imply you can call this function.

@aplavin
Copy link
Contributor

aplavin commented Oct 6, 2025

It's up to package authors to decide whether they consider extension module names public or not. For packages that do, get_extension(ThatPackage, :SomeNameExt) is totally well-defined and relies only on public behavior.

Also, this function can totally legitimately be used in the package defining the extension itself.

@vtjnash
Copy link
Member Author

vtjnash commented Oct 6, 2025

They cannot, since this is private to Base. Particular not in the package itself, since that means the package loads its own extension, which will trigger at lot of issues

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs This change adds or pertains to documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants