Skip to content

Commit d896d40

Browse files
Document the explicit FunctionWrappersWrapper{FW, P, CS}(fw, cs) constructor (#79)
* Restore the ExplicitImports ignores dropped in #76 #76 replaced the whole `run_qa(...)` call with a bare `run_qa(FunctionWrappersWrappers)`, which silently discarded the `all_qualified_accesses_are_public` ignore list it carried. The QA group has errored on `main` ever since with `NonPublicQualifiedAccessException` for `FunctionWrappers.FunctionWrapper` and `TruncatedStacktraces.@truncate_stacktrace`. This is invisible to `Pkg.test()`, which runs the curated default group; QA is not part of it. `:tail` is not restored: `Base.tail` is no longer reached, and ExplicitImports does not flag it. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> * Drop the dead TruncatedStacktraces dependency `@truncate_stacktrace` cannot fire in this package. TruncatedStacktraces sets `DISABLE = @load_preference("disable", true) || VERSION >= v"1.10"`, and the macro body is wrapped in `@static if !DISABLE`, so on Julia 1.10 and later it expands to nothing — and 1.10 is this package's floor. The `Base.show` method it is supposed to define has never existed on any Julia version we support, and the preference cannot override the version clause. Verified: `FunctionWrappersWrapper` contributes zero `Base.show` methods, and its type prints in full with no truncation. That makes the dependency dead weight, and it was the only reason the QA suite needed a `@truncate_stacktrace` ignore. Removing it is better than either ignoring the access or promoting the name upstream — the latter is impossible in any case, since SciML/TruncatedStacktraces.jl is archived and read-only. Only the `FunctionWrapper` ignore remains, and that one has a path out now: JuliaLang/FunctionWrappers.jl#35. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> * Document the explicit FunctionWrappersWrapper{FW, P, CS}(fw, cs) constructor `FunctionWrappersWrapper` is exported, so its inner constructor was already reachable as public API, but it carried no docstring — the only constructor of the type that did not. Downstream solver stacks construct through exactly this method, because supplying `FW`, `P` and `CS` directly keeps the wrapper type inferrable without relying on constant propagation through a keyword-argument frame, which the `argtypes`/`rettypes` and tuple constructors do. The docstring is attached with `@doc` on the method signature after the struct; a docstring written inside the struct body does not attach to the type's binding, so Documenter would never render it. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> --------- Co-authored-by: ChrisRackauckas-Claude <accounts@chrisrackauckas.com>
1 parent 689ef3b commit d896d40

3 files changed

Lines changed: 57 additions & 6 deletions

File tree

Project.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
name = "FunctionWrappersWrappers"
22
uuid = "77dc65aa-8811-40c2-897b-53d922fa7daf"
33
authors = ["Chris Elrod <elrodc@gmail.com> and contributors"]
4-
version = "1.11.0"
4+
version = "1.11.1"
55

66
[deps]
77
FunctionWrappers = "069b7b12-0de2-55c6-9aab-29f3d0a68a2e"
88
PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
99
SciMLPublic = "431bcebd-1456-4ced-9d72-93c2757fff0b"
10-
TruncatedStacktraces = "781d530d-4396-4725-bb49-402e4bee1e77"
1110

1211
[weakdeps]
1312
Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9"
@@ -28,7 +27,6 @@ SafeTestsets = "0.1, 1"
2827
SciMLPublic = "1"
2928
SciMLTesting = "2.4"
3029
Test = "1"
31-
TruncatedStacktraces = "1.1"
3230
julia = "1.10"
3331

3432
[extras]

src/FunctionWrappersWrappers.jl

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ module FunctionWrappersWrappers
22

33
using FunctionWrappers: FunctionWrappers
44
using SciMLPublic: @public
5-
import TruncatedStacktraces
65

76
export FunctionWrappersWrapper, unwrap, wrapped_signatures, wrapped_return_types
87
export NoCache, SingleCache, DictCache
@@ -223,7 +222,49 @@ struct FunctionWrappersWrapper{FW, P, CS}
223222
end
224223
end
225224

226-
TruncatedStacktraces.@truncate_stacktrace FunctionWrappersWrapper
225+
@doc """
226+
FunctionWrappersWrapper{FW, P, CS}(fw, cs) -> FunctionWrappersWrapper{FW, P, CS}
227+
228+
Create a `FunctionWrappersWrapper` from an already-built wrapper tuple and cache storage,
229+
with every type parameter fixed by the caller.
230+
231+
This is the fully explicit form. Prefer it when the result type must be inferrable from
232+
type parameters alone: `FW`, `P` and `CS` are given directly rather than derived from
233+
argument values, so nothing rests on constant propagation through a keyword-argument
234+
frame. Solver stacks that wrap a type-erased callable — where the wrapper type, and every
235+
cache built from it, must stay concrete — construct through this method.
236+
237+
The caller is responsible for consistency: `fw` must match `FW`, and `cs` must be the
238+
storage type `P`'s fallback path expects — [`NoCacheStorage`](@ref),
239+
[`SingleCacheStorage`](@ref), or [`DictCacheStorage`](@ref), matching the intended cache
240+
mode.
241+
242+
# Arguments
243+
- `fw`: Tuple of `FunctionWrappers.FunctionWrapper`s, tried in order on call.
244+
- `cs`: Cache storage instance used by the fallback path.
245+
246+
# Type Parameters
247+
- `FW`: Tuple type of the wrapped `FunctionWrapper`s.
248+
- `P`: Fallback policy type, such as `Strict`, `AllowAll`, or `AllowNonIsBits`.
249+
- `CS`: Cache storage type, matching `typeof(cs)`.
250+
251+
# Returns
252+
- `FunctionWrappersWrapper{FW, P, CS}`: A callable wrapper around `fw`.
253+
254+
# Examples
255+
```jldoctest
256+
julia> using FunctionWrappers: FunctionWrapper
257+
258+
julia> fw = (FunctionWrapper{Float64, Tuple{Float64, Float64}}(+),);
259+
260+
julia> cs = FunctionWrappersWrappers.SingleCacheStorage();
261+
262+
julia> fww = FunctionWrappersWrapper{typeof(fw), AllowNonIsBits, typeof(cs)}(fw, cs);
263+
264+
julia> fww(1.0, 2.0)
265+
3.0
266+
```
267+
""" FunctionWrappersWrapper{FW, P, CS}(fw::FW, cs::CS) where {FW, P, CS}
227268

228269
"""
229270
FunctionWrappersWrapper{FW, P, CS}(f) -> FunctionWrappersWrapper{FW, P, CS}

test/qa/qa.jl

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
11
using SciMLTesting, FunctionWrappersWrappers
22

3-
run_qa(FunctionWrappersWrappers)
3+
run_qa(
4+
FunctionWrappersWrappers;
5+
ei_kwargs = (;
6+
# `FunctionWrappers.FunctionWrapper` is not declared `public` in its owning
7+
# module. It is the type this package exists to wrap: it appears in the
8+
# signature of every public constructor, and callers must build
9+
# `FunctionWrapper` tuples themselves to reach the inference-stable
10+
# construction path, so it cannot be hidden behind our own API. Drop this
11+
# entry once JuliaLang/FunctionWrappers.jl#41 is released and the compat
12+
# floor is raised.
13+
all_qualified_accesses_are_public = (; ignore = (:FunctionWrapper,)),
14+
),
15+
)

0 commit comments

Comments
 (0)