#5137 pkg_mkIndex fails on package present

obsolete: 8.5.13
Don Porter

OS: Debian Squeeze
Tcl: 8.5 (Expect 5.44)

Problem: pkg_mkIndex does not stub "package present"

Expected: as pkg_mkIndex stubs all package handling procedures, it should not enforce that assertion --> ignore "package present" in pkg_mkIndex

* assume package foo requires package bar
* when using foo, I can therefore assert "package present bar"
* this should break, if and only if foo no longer requires bar

Please consider the fix in 8.6 as well!


  • Don Porter
    Don Porter

    What would the stubbed [package present] do?
    What should it return?

    This seems easy to work around. I'd suspect
    anything calling [package present] after an
    earlier [package require] might benefit from some

    Looking ahead, there's not a lot of support for continuing
    to try to offer a [pkg_mkIndex] command (think Tcl 9),
    because it's an impossible problem to solve in the general
    case, and in the simple cases where it's possible, it's still
    a greater burden, and delivers less powerful and flexible
    results than you can get from just creating the pkgIndex.tcl
    file yourself (perhaps with minimal substitution assistance
    from configure to help with maintenance).

    That said, I'll fix this one if you can clarify what answer your
    script expects a stubbed [package present] to return, and can
    give me some assurance there aren't other scripts expecting
    a different answer.

  • heinrichmartin

    Hi Don,

    [package require] returns the empty string inside [pkg_mkIndex]. I think this is the way to go for [package present]. (No assurance that this is what everybody would expect...)

    The discontinued support for pkg_mkIndex is a valuable information:
    I use it in the Makefile of a project with several packages. The purpose is to detect simple syntax errors like mismatched delimiters. (Yes, otherwise I could create them manually.)

    Maybe, my error is something completely different, that's why I want to clarify with a minimal example:
    cd /tmp
    mkdir foo
    cat > foo/init.tcl <<EOF
    package provide foo 4.2
    package require bar
    namespace eval foo { proc foo1 args { return [info level 0] } }
    expect -c "pkg_mkIndex -verbose foo"
    mkdir bar
    cat > bar/init.tcl <<EOF
    package provide bar 2.8
    namespace eval bar { proc bar1 args { return [info level 0] } }
    expect -c "pkg_mkIndex -verbose bar"
    mkdir test
    cat > test/init.tcl <<EOF
    puts ">>>[package require foo]<<<"
    puts ">>>[package present bar]<<<"
    package provide test 0.1
    # sourcing test/init.tcl works fine
    export TCLLIBPATH="." && expect -c "source test/init.tcl"
    # but pkg_mkIndex does not
    export TCLLIBPATH="." && expect -c "pkg_mkIndex -verbose test"

    Thanks for your reply!

  • Don Porter
    Don Porter

    For the minimal example you present, the best solution
    is really to replace the [package present bar] in
    test/init.tcl with [package require bar]. pkg_mkIndex
    would then handle it and in the context presented, the
    functionality would be identical, bailing out with an
    error whenever package bar was not present.

    I suspect your actual use case may have more
    plausible reasons for using [package present].

  • Don Porter
    Don Porter

    A script like this is more trouble:

    package require bar
    if {[package vsatisfies [package present bar] 2]} {
    # import commands from bar version 2
    } else {
    package require util 1
    # install syntax conversion wrappers between
    # versions 1 and 2 of bar, using facilities of package util

    If package "bar" is a [load]-able package, the
    the [pkg_mkIndex -load bar] option can control
    the presence of bar during indexing. In that
    scenario, stubbing [package present] would make
    a currently functioning indexing operation stop

    A simple rewrite [package present] -> [package provide]
    would solve the problem, but that sort of potential incompat
    ought to be introduced in 8.6 (if at all), not a patchlevel, IMHO.

  • Don Porter
    Don Porter

    Another thing to consider is in your use of [pkg_mkIndex], what control
    do you have over which version of Tcl's [pkg_mkIndex] gets used?

    If you're using it completely "in house" to perform your own development
    tasks, then you have control, and using that control, you can patch your
    local proc to do what you ask. Very simple patch. Change the lines in
    tcl/library/package.tcl from:

    switch -- $what {
    require {
    return; # Ignore transitive requires


    switch -- $what {
    present - require {
    return; # Ignore transitive requires

    However, if you're deploying, say, Makefiles to systems unknown,
    and relying on using whatever local tclsh or expect program happen
    to be installed, you're going to have no choice but to continue
    accommodating the older [pkg_mkIndex] behavior, so the way forward
    is to rewrite your scripts to revise/remove their use of the [package present]
    command, and/or move off of [pkg_mkIndex] as a tool completely.

    I hope you can see why we maintainers just don't have much enthusiasm
    for attempts to improve [pkg_mkIndex]. It's just not a problem suited for
    a good simple and general solution.

    If I'm overlooking or misunderstanding something, I welcome your further
    thoughts on the matter.

  • heinrichmartin

    Fair enough.

    My way to use [package present] was as an assertion and to help the IDE, which I though was more lightweight than [package require].

    Others might use it to decide their implementation strategy, but then: they too could use if {[catch {package require ...}]}

    Maybe I do not fully understand the difference between [package require] and [package present], but I understand that it makes no difference in my case. Even the overhead using [package require] is negligible when assuming the package is present anyway.

    Thx for reviewing this "issue"!

  • heinrichmartin

    • status: open --> open-wont-fix