From 8a971a66952cb039708124d37e7956c68501a25a Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Tue, 10 Jun 2025 15:11:39 -0400 Subject: [PATCH] restore fallback 3-arg `setprecision` method (#58586) fixes #55899 --------- Co-authored-by: Sukera <11753998+Seelengrab@users.noreply.github.com> (cherry picked from commit cdb158b58c9f0be4281fef1631c9c6e796532900) --- NEWS.md | 5 +++++ base/mpfr.jl | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/NEWS.md b/NEWS.md index f2e667378e5a0..9dee73bda6898 100644 --- a/NEWS.md +++ b/NEWS.md @@ -134,6 +134,8 @@ New library features * `Timer` now has readable `timeout` and `interval` properties, and a more descriptive `show` method ([#57081]). * `sort` now supports `NTuple`s ([#54494]). * `map!(f, A)` now stores the results in `A`, like `map!(f, A, A)` or `A .= f.(A)` ([#40632]). +* `setprecision` with a function argument (typically a `do` block) is now thread safe. Other forms + should be avoided, and types should switch to an implementation using `ScopedValue` ([#51362]). Standard library changes ------------------------ @@ -225,8 +227,10 @@ Tooling Improvements [#40989]: https://github.com/JuliaLang/julia/issues/40989 [#45793]: https://github.com/JuliaLang/julia/issues/45793 [#49355]: https://github.com/JuliaLang/julia/issues/49355 +[#49933]: https://github.com/JuliaLang/julia/issues/49933 [#50988]: https://github.com/JuliaLang/julia/issues/50988 [#51149]: https://github.com/JuliaLang/julia/issues/51149 +[#51362]: https://github.com/JuliaLang/julia/issues/51362 [#51810]: https://github.com/JuliaLang/julia/issues/51810 [#52103]: https://github.com/JuliaLang/julia/issues/52103 [#52999]: https://github.com/JuliaLang/julia/issues/52999 @@ -284,3 +288,4 @@ Tooling Improvements [#57087]: https://github.com/JuliaLang/julia/issues/57087 [#57109]: https://github.com/JuliaLang/julia/issues/57109 [#57253]: https://github.com/JuliaLang/julia/issues/57253 +[#57727]: https://github.com/JuliaLang/julia/issues/57727 diff --git a/base/mpfr.jl b/base/mpfr.jl index 0d52510447b2f..2175fb56cc526 100644 --- a/base/mpfr.jl +++ b/base/mpfr.jl @@ -1178,9 +1178,29 @@ Often used as `setprecision(T, precision) do ... end` Note: `nextfloat()`, `prevfloat()` do not use the precision mentioned by `setprecision`. +!!! warning + There is a fallback implementation of this method that calls `precision` + and `setprecision`, but it should no longer be relied on. Instead, you + should define the 3-argument form directly in a way that uses `ScopedValue`, + or recommend that callers use `ScopedValue` and `@with` themselves. + !!! compat "Julia 1.8" The `base` keyword requires at least Julia 1.8. """ +function setprecision(f::Function, ::Type{T}, prec::Integer; kws...) where T + depwarn(""" + The fallback `setprecision(::Function, ...)` method is deprecated. Packages overloading this method should + implement their own specialization using `ScopedValue` instead. + """, :setprecision) + old_prec = precision(T) + setprecision(T, prec; kws...) + try + return f() + finally + setprecision(T, old_prec) + end +end + function setprecision(f::Function, ::Type{BigFloat}, prec::Integer; base::Integer=2) Base.ScopedValues.@with(CURRENT_PRECISION => _convert_precision_from_base(prec, base), f()) end