Bwidget Source Code
View Ticket
Not logged in
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to [email protected]
or submit via the online form by Sep 9.
Ticket UUID: c86207db01fc9ce03821ff0fecdceac6a23456f2
Title: Deleting internal namespaces is not ok any more with BWidget 1.9.9
Type: Bug Version: 1.9.9
Submitter: oehhar Created on: 2016-07-11 14:17:02
Subsystem: bwidget 1.x Assigned To: nobody
Priority: 5 Medium Severity: Minor
Status: Closed Last Modified: 2016-07-20 14:21:26
Resolution: Fixed Closed By: oehhar
    Closed on: 2016-07-20 14:21:26
Description:

JB Gardette reported on clt thread "BWidget 1.9.10 bug ?" the 8.7.2016:

Tcl 8.6.4

The following script :

    package require BWidget

    set listPersistentNameSpace [namespace children]

    toplevel .t1

    pack [ComboBox .t1.c1]

    tkwait window .t1

    foreach nameSpaceName [namespace children] {
        
        if {$nameSpaceName ni $listPersistentNameSpace} {
            
            namespace delete $nameSpaceName
        }
    }

    toplevel .t2

    pack [ComboBox .t2.c2]
  • Works with BWidget 1.9.8
  • Crashes with BWidget 1.9.10

Error message :

invalid command name "::ComboBox::create"
    while executing
"ComboBox .t.c2"
    invoked from within
"pack [ComboBox .t.c2]"

User Comments: oehhar added on 2016-07-20 14:21:26:

Author verified effectiveness. Close bug.


adrianmedranocalvo (claiming to be Adrián Medraño Calvo <[email protected]>) added on 2016-07-15 10:52:23:
Sure!  Please go ahead and merge it.  We might want this to become a new release...

Best regards,
Adrián.

oehhar added on 2016-07-15 10:23:52:

Dear Adriàn,

I tested it with 8.4-8.6 and all ok.

I asked the author on all channels. I suppose it came from France and they have a long week-end and the start of the holiday season, so there might be a delay.

If it is ok for you, I favor to commit this change as it sounds reasonable to me.

Thank you, Harald


adrianmedranocalvo (claiming to be Adrián Medraño Calvo <[email protected]>) added on 2016-07-15 07:31:39:
Hello Harald,

that's mostly what happens, only that 'package require BWidget' does not actually load the commands but only registers the autoloads.  You can try the following in tclsh to check:

% package require BWidget
1.9.10
% namespace children
::GlobalVar ::ttk ::Widget ::oo ::BWIDGET ::BWidget ::msgcat ::zlib ::pkg ::tcl ::auto_mkindex_parser ::tk
% ComboBox XXXX
bad window path name "XXXX"
% namespace children
::Entry ::GlobalVar ::DragSite ::ttk ::Widget ::ListBox ::DynamicHelp ::oo ::BWIDGET ::BWidget ::ArrowButton ::msgcat ::ComboBox ::zlib ::DropSite ::pkg ::tcl ::auto_mkindex_parser ::tk

Note how the namespace are created only after invoking ComboBox.

With regards to the report, I agree that the auto-load feature is being somewhat abused.  Could you ask the original reporter what's their actual purpose?  Perhaps BWidget is not properly cleaning something...

I somehow thought you were using older Tcl versions in your applications (8.0?).  In any case both tests would be very useful: running the provided testcase and just launching some of your bigger applications with the changes.

Thank you und beste Grüße

Adrián

oehhar added on 2016-07-14 15:14:29:

Thank you, Adriàn,

First of all, I don't think we should allow that our namespaces are deleted. So, for me, the ticket is quite invalid.

What I understand from your comment:

  • Commands are loaded by 'package require Bwidget'
  • Commands are deleted by 'namespace delet ::Entry'
  • The autoload mechanism brings the command (and corresponding namespace) back by just invoking "Entry".
  • The last step does not work any more from BWidget 1.9.9 on, as the command "Entry" is searched in the global namespace, but is only present in namespace:':Entry'.
  • The patch defines it in a way that it is again found in the global namespace

Anyway, it is not important that I understand what is happening.

I can try [e49079d49e] from 8.4 to 8.6 if this is what you required. Try what:

  • the test case with the deletion ?
  • just normal operation (widget demo) ?

Thank you, Harald


adrianmedranocalvo (claiming to be Adrián Medraño Calvo <[email protected]>) added on 2016-07-12 19:09:47:
This is a consequence of a drive-by change in the namespace patch.

The issue comes from the auto_load mechanism.  When invoking an auto_loaded command, the unknown handler ends up being invoked to resolve it.  The invoked command is normalized via auto_qualify before comparing it with what's declared in the pkgIndex.tcl; that mostly means fully-qualifying it (i.e. from ComboBox::create to ::ComboBox::create).  But (!) there's a workaround that allows unqualified commands to find their autoload when the latter was declared unqualified as well.  See commentary excerpt from "auto_load" in init.tcl:

[...]
    # workaround non canonical auto_index entries that might be around
    # from older auto_mkindex versions
    lappend nameList $cmd
[...]

That is, the unqualified command (if invoked unqualified) is also looked up.

This has allowed everything to work fine until last year, when while changing BWidget to support different namespaces, I made sure creation commands are aliased to their fully qualified version.  That is, instead of invoking "ComboBox::create" we now invoke "::ComboBox::create".  This has caused the auto_qualify workaround to no longer apply.

I committed a fix in branch [bug-c86207db01fc9ce0] based on the auto_qualify commentary:

▸       # For historical reasons, commands in the global namespace do not have leading
▸       # :: in the index key. The list has two elements when the command name is

That is, top-level commands should be declared unqualified, others qualified.  This should work with all Tcl releases (see that very comment in 1998's http://core.tcl.tk/tcl/artifact/cc260c504331f6b2#auto_qualify).

Could you please check it with out?  Especially with old Tcl releases...

Best regards,
Adrián.

oehhar added on 2016-07-11 14:21:33:

I can verify this with TCL 8.5.18 too.

The removed namespaces are:

  • ::Entry
  • ::DragSite
  • ::ListBox
  • ::DynamicHelp
  • ::ArrowButton
  • ::ComboBox
  • ::DropSite

For 1.9.8, they are rebuild on the second command, on 1.9.9 they are not rebuild and thus we get the error.

I don't know if this is a bug. Maybee, others may comment on it.

_ Harald