Closed mzgubic closed 3 years ago
So is the proposal here to have @reexport using X
avoid exporting a binding if it's deprecated by X
? Note that would turn deprecations, which are typically non-breaking, into hard errors downstream.
I think the opposite, I think the problem is right now it doesn't reexport the old names?
The problem is that my_old_sum
now is not exported so it breaks other people's code.
julia> module LargePackage
using Reexport
module SmallPackage
export my_new_sum
my_new_sum(A::Tuple) = reduce(+, A)
Base.@deprecate_binding my_old_sum my_new_sum
end
@reexport using .SmallPackage
end # module
Main.LargePackage
julia> using .LargePackage
julia> my_old_sum((1, 2))
ERROR: UndefVarError: my_old_sum not defined
Stacktrace:
[1] top-level scope
@ REPL[3]:1
Curiously, if we use @deprecate
here it just works.
Curiously, if we use
@deprecate
here it just works.
That's because the expansion of @deprecate
includes an export
by default. One of the arguments to the macro toggles that.
Okay, I see the problem now: names
doesn't see deprecated bindings by default (that's documented). I think that instead of iterating over names(M)
for M
a Module
, we'd need to do something like
for binding in names(M; all=true, imported=true)
if Base.isexported(M, binding)
# reexport binding
end
end
This came up recently when we renamed a few types in
ChainRules
, which uses@reexport
macro to reexport theChainRulesCore
differential types, e.g.Zero
was renamed toZeroTangent
.This broke
ReversePropagation
tests (as part of theChainRules
integration tests suite) becauseReversePropagation
only depends onChainRules
directly (rather thanChainRulesCore
), and did not understand the deprecatedZero
.