Skip to content

Fix stale undefined exports (Variable, Unknown)#1906

Merged
ChrisRackauckas merged 1 commit into
JuliaSymbolics:masterfrom
ChrisRackauckas-Claude:fix-stale-variable-export-undefined-unknown
Jun 22, 2026
Merged

Fix stale undefined exports (Variable, Unknown)#1906
ChrisRackauckas merged 1 commit into
JuliaSymbolics:masterfrom
ChrisRackauckas-Claude:fix-stale-variable-export-undefined-unknown

Conversation

@ChrisRackauckas-Claude

Copy link
Copy Markdown
Contributor

Problem

names(Symbolics) currently lists two names that do not resolve in the module, so Aqua.test_undefined_exports(Symbolics) fails and a blanket @reexport using Symbolics leaks an undefined binding into downstream packages (this is what forced the workaround in SciML/Corleone.jl#86).

On Julia 1.12 with Symbolics v7.28.1 / current master:

julia> using Symbolics
julia> filter(n -> !isdefined(Symbolics, n), names(Symbolics))
2-element Vector{Symbol}:
 :Unknown
 :Variable

julia> using Aqua
julia> Aqua.test_undefined_exports(Symbolics)   # FAILS
# Evaluated: isempty([Symbolics.Unknown, Symbolics.Variable])

Root cause

  • Variable is exported at src/Symbolics.jl:170, but the struct Variable{T} end (a deprecated shim that redirected to variable(name, idx...; T=T)) was removed in 55a3d1a ("refactor: use @syms parsing for @variables") without dropping it from the export list. The binding has not existed since.
  • Unknown was marked @public in 5d78c7a ("refactor: mark Unknown as public"), but SymbolicUtils.Unknown was never brought into the Symbolics namespace, so the public name had nothing to resolve to. SymbolicUtils does not export Unknown, so @reexport using SymbolicUtils does not bring it in either.

Fix

  • Drop Variable from the export (the public replacement is variable(...)).
  • Import Unknown alongside the other SymbolicUtils names so the @public Unknown resolves (Symbolics.Unknown === SymbolicUtils.Unknown). This matches how Unknown is already referenced throughout the source as SymbolicUtils.Unknown.

Verification (Julia 1.12)

  • Before: Aqua.test_undefined_exports(Symbolics) fails ([Symbolics.Unknown, Symbolics.Variable]).
  • After: Aqua.test_undefined_exports(Symbolics) passes; filter(n -> !isdefined(Symbolics, n), names(Symbolics)) is empty; Symbolics.Unknown === SymbolicUtils.Unknown; core smoke test (@variables, derivative, variable(:z), Unknown(2)) still works.

Runic: the two changed lines are Runic-clean (sciml style). The file has unrelated pre-existing Runic drift in a precompile block near the bottom, which is left untouched to keep the diff minimal.


Please ignore until reviewed by @ChrisRackauckas.

🤖 Generated with Claude Code

…Unknown`

`names(Symbolics)` listed two names that do not resolve in the module, so
`Aqua.test_undefined_exports` fails and `@reexport using Symbolics`
leaks an undefined binding into downstream packages:

- `Variable`: `export`ed at src/Symbolics.jl:170, but the `struct Variable{T} end`
  (deprecated, redirecting to `variable(name, idx...; T=T)`) was removed in
  55a3d1a ("refactor: use `@syms` parsing for `@variables`") without dropping
  it from the export list. Removed from the export.
- `Unknown`: marked `@public` in 5d78c7a ("refactor: mark `Unknown` as public"),
  but `SymbolicUtils.Unknown` was never brought into the `Symbolics` namespace, so
  the public name did not resolve. Imported it alongside the other SymbolicUtils
  names so `Symbolics.Unknown === SymbolicUtils.Unknown`.

Verified on Julia 1.12: `Aqua.test_undefined_exports(Symbolics)` fails before
(`[Symbolics.Unknown, Symbolics.Variable]`) and passes after.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ChrisRackauckas-Claude pushed a commit to ChrisRackauckas-Claude/Corleone.jl that referenced this pull request Jun 21, 2026
The manual Symbolics re-export loop works around an undefined `Variable`
export (and `@public Unknown`) in Symbolics. Both are fixed upstream in
JuliaSymbolics/Symbolics.jl#1906; the comment now records that the loop can be
replaced with `@reexport using Symbolics` plus a Symbolics compat-floor bump
once that lands.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@codecov-commenter

codecov-commenter commented Jun 21, 2026

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 80.75%. Comparing base (c736678) to head (bed0571).
⚠️ Report is 159 commits behind head on master.
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@             Coverage Diff             @@
##           master    #1906       +/-   ##
===========================================
+ Coverage   26.12%   80.75%   +54.63%     
===========================================
  Files          56       59        +3     
  Lines        5356     5732      +376     
===========================================
+ Hits         1399     4629     +3230     
+ Misses       3957     1103     -2854     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ChrisRackauckas ChrisRackauckas marked this pull request as ready for review June 22, 2026 12:42
@ChrisRackauckas ChrisRackauckas merged commit 7785001 into JuliaSymbolics:master Jun 22, 2026
18 of 24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants