Skip to content

Declare the documented non-exported API public - #280

Closed
ChrisRackauckas-Claude wants to merge 1 commit into
LCSB-BioCore:masterfrom
ChrisRackauckas-Claude:public-api-declarations
Closed

Declare the documented non-exported API public#280
ChrisRackauckas-Claude wants to merge 1 commit into
LCSB-BioCore:masterfrom
ChrisRackauckas-Claude:public-api-declarations

Conversation

@ChrisRackauckas-Claude

Copy link
Copy Markdown

Opened as a draft — please ignore until reviewed by @ChrisRackauckas.

Problem

SBML.Model, the SBML.Math AST types (MathApply, MathIdent, ...) and the documented data accessors (extensive_kinetic_math, initial_amounts, seemsdefined, ...) are the package's user-facing interface. They are documented in the manual, but none of them are exported, and deliberately so: using SBML should not inject generic names like Model, Species or Version into the caller's namespace.

The side effect is that there is no machine-checkable distinction between intended API and internals. Downstream packages have to reach for SBML.Model and SBML.MathApply(...) with no signal that these are supported, and linting tools such as ExplicitImports.jl flag every one of those accesses as a private-name dependency. This came up concretely in SBMLToolkit.jl, which builds SBML.MathApply nodes and reads MathApply.args while walking SBML math trees (SciML/SBMLToolkit.jl#223).

Change

Declare those names public, so Base.ispublic(SBML, name) agrees with what the manual already says.

public is a Julia 1.11 feature and this package's compat floor is 1.6, so the declaration goes through eval(Expr(:public, ...)) behind a @static if VERSION >= v"1.11" guard — a bare public ... is a syntax error on older versions. No new dependency; on Julia < 1.11 it is a no-op.

Declared public (51 names, all of which already have docstrings rendered on the function reference page):

  • types.jlMaybe, VPtr (both appear in documented signatures; user-written converters are VPtr -> Nothing)
  • structs.jl — the full struct family, SBMLObject through Model, including the Math AST and the GeneProductAssociation / Rule hierarchies
  • version.jlVersion
  • interpret.jlinterpret_math, default_function_mapping, default_constants
  • unitful.jlunitful
  • utils.jlextensive_kinetic_math, fbc_flux_objective, kinetic_flux_objective, get_compartment_size, initial_amounts, initial_concentrations, isfreein, seemsdefined, test_suite_url

Deliberately left alone, as implementation details that happen to carry docstrings: the readsbml.jl parser helpers (_readSBML, get_model, get_association, get_optional_*, get_string, ...), mayfirst / maylift, check_errors / get_error_messages, sbml, and everything in math.jl (already labelled "Internal math helpers" in the docs). Happy to move any of these across if you consider them supported.

Julia has no field-level visibility, so making a struct type public is also the strongest available statement about its documented fields. docs/src/functions.md now says this explicitly, along with the exported-or-public rule and the Base.ispublic check.

Tests

New test/public.jl, run from runtests.jl:

  • every listed name is defined and has a docstring (all Julia versions)
  • on 1.11+, every listed name is ispublic and not exported
  • on 1.11+, every name reachable via using SBML is also ispublic

That last one is the useful regression guard: it fails if an export is added without the maintainers thinking about the public surface.

Verification

Run locally, output observed:

  • Pkg.test() on Julia 1.12.6 — 719 Pass, 1 Broken, 720 Total (the broken test is pre-existing on master)
  • Pkg.test() on Julia 1.10.11 (CI LTS) — 556 Pass, 1 Broken, 557 Total
  • test/public.jl alone — 265 passing assertions on 1.12, 102 on 1.10 (the ispublic assertions are correctly skipped below 1.11)
  • using SBML loads clean on 1.10.11, confirming the version guard does not break the pre-1.11 path
  • JuliaFormatter.format(".") produces no diff on the changed files

One unrelated formatting drift the current JuliaFormatter wants in test/loadmodels.jl (doc -> begindoc->begin) was reverted to keep this diff focused.

Note on versioning

This adds public API, so by SemVer it warrants a minor bump (1.6 → 1.7). I left Project.toml untouched since releases are yours to cut — say the word and I will add the bump.

`SBML.Model`, the `SBML.Math` AST types, and the documented data accessors
are the package's user-facing interface, but none of them are exported --
`using SBML` would otherwise inject generic names like `Model`, `Species`
and `Version` into the caller's namespace. That leaves downstream packages
with no machine-checkable way to tell intended API from internals, and tools
like ExplicitImports flag every `SBML.Model` as reaching into a private name.

Declare those names `public` so `Base.ispublic` reflects what the manual
already documents. `public` needs Julia 1.11 and this package supports 1.6,
so the declaration is an `eval(Expr(:public, ...))` behind a version guard;
a bare `public ...` would be a syntax error on older versions.

Parser helpers (`get_optional_*`, `get_string`, `_readSBML`, ...), the
`Maybe` combinators, `sbml`, and the math helpers in `math.jl` are left
alone, since they are implementation details that happen to have docstrings.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
@exaexa

exaexa commented Jul 30, 2026

Copy link
Copy Markdown
Member

Pure LLM contributions are not acceptable, please reopen once this is reviewed and sliced into single-topic changes.

Also note that the notion of "public" API for the structures is somewhat smudgy here, as it depends very much on what the current SBML semantics are (oit of our control).

@exaexa exaexa closed this Jul 30, 2026
@ChrisRackauckas

Copy link
Copy Markdown
Contributor

What is wrong with the PR? It's a very narrow single topic. Is there a specific thing you don't think should be marked as public?

@ChrisRackauckas

Copy link
Copy Markdown
Contributor

Do you instead want all of those removed from the documentation?

@ChrisRackauckas

Copy link
Copy Markdown
Contributor

Bump

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