gh-75552: Remove deprecated tkinter.tix module (GH-104902)

This commit is contained in:
Zachary Ware 2023-05-27 12:34:19 -05:00 committed by GitHub
parent 86d8f48935
commit a989b73e8e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 18 additions and 2719 deletions

View File

@ -235,7 +235,6 @@ epub_publisher = 'Python Software Foundation'
# match any of the following regexes (using re.match). # match any of the following regexes (using re.match).
coverage_ignore_modules = [ coverage_ignore_modules = [
r'[T|t][k|K]', r'[T|t][k|K]',
r'Tix',
] ]
coverage_ignore_functions = [ coverage_ignore_functions = [

View File

@ -46,15 +46,8 @@ One solution is to ship the application with the Tcl and Tk libraries, and point
to them at run-time using the :envvar:`TCL_LIBRARY` and :envvar:`TK_LIBRARY` to them at run-time using the :envvar:`TCL_LIBRARY` and :envvar:`TK_LIBRARY`
environment variables. environment variables.
To get truly stand-alone applications, the Tcl scripts that form the library Various third-party freeze libraries such as py2exe and cx_Freeze have
have to be integrated into the application as well. One tool supporting that is handling for Tkinter applications built-in.
SAM (stand-alone modules), which is part of the Tix distribution
(https://tix.sourceforge.net/).
Build Tix with SAM enabled, perform the appropriate call to
:c:func:`Tclsam_init`, etc. inside Python's
:file:`Modules/tkappinit.c`, and link with libtclsam and libtksam (you
might include the Tix libraries as well).
Can I have Tk events handled while waiting for I/O? Can I have Tk events handled while waiting for I/O?

View File

@ -12,8 +12,7 @@ Graphical User Interfaces with Tk
Tk/Tcl has long been an integral part of Python. It provides a robust and Tk/Tcl has long been an integral part of Python. It provides a robust and
platform independent windowing toolkit, that is available to Python programmers platform independent windowing toolkit, that is available to Python programmers
using the :mod:`tkinter` package, and its extension, the :mod:`tkinter.tix` and using the :mod:`tkinter` package, and its extension, the :mod:`tkinter.ttk` module.
the :mod:`tkinter.ttk` modules.
The :mod:`tkinter` package is a thin object-oriented layer on top of Tcl/Tk. To The :mod:`tkinter` package is a thin object-oriented layer on top of Tcl/Tk. To
use :mod:`tkinter`, you don't need to write Tcl code, but you will need to use :mod:`tkinter`, you don't need to write Tcl code, but you will need to
@ -39,7 +38,6 @@ alternative `GUI frameworks and tools <https://wiki.python.org/moin/GuiProgrammi
tkinter.scrolledtext.rst tkinter.scrolledtext.rst
tkinter.dnd.rst tkinter.dnd.rst
tkinter.ttk.rst tkinter.ttk.rst
tkinter.tix.rst
idle.rst idle.rst
.. Other sections I have in mind are .. Other sections I have in mind are

View File

@ -252,10 +252,6 @@ Additional modules:
(experimental) Drag-and-drop support for :mod:`tkinter`. This will (experimental) Drag-and-drop support for :mod:`tkinter`. This will
become deprecated when it is replaced with the Tk DND. become deprecated when it is replaced with the Tk DND.
:mod:`tkinter.tix`
(deprecated) An older third-party Tcl/Tk package that adds several new
widgets. Better alternatives for most can be found in :mod:`tkinter.ttk`.
:mod:`turtle` :mod:`turtle`
Turtle graphics in a Tk window. Turtle graphics in a Tk window.

View File

@ -1,583 +0,0 @@
:mod:`tkinter.tix` --- Extension widgets for Tk
===============================================
.. module:: tkinter.tix
:synopsis: Tk Extension Widgets for Tkinter
.. sectionauthor:: Mike Clarkson <mikeclarkson@users.sourceforge.net>
**Source code:** :source:`Lib/tkinter/tix.py`
.. index:: single: Tix
.. deprecated:: 3.6
This Tk extension is unmaintained and should not be used in new code. Use
:mod:`tkinter.ttk` instead.
--------------
The :mod:`tkinter.tix` (Tk Interface Extension) module provides an additional
rich set of widgets. Although the standard Tk library has many useful widgets,
they are far from complete. The :mod:`tkinter.tix` library provides most of the
commonly needed widgets that are missing from standard Tk: :class:`HList`,
:class:`ComboBox`, :class:`Control` (a.k.a. SpinBox) and an assortment of
scrollable widgets.
:mod:`tkinter.tix` also includes many more widgets that are generally useful in
a wide range of applications: :class:`NoteBook`, :class:`FileEntry`,
:class:`PanedWindow`, etc; there are more than 40 of them.
With all these new widgets, you can introduce new interaction techniques into
applications, creating more useful and more intuitive user interfaces. You can
design your application by choosing the most appropriate widgets to match the
special needs of your application and users.
.. seealso::
`Tix Homepage <https://tix.sourceforge.net/>`_
The home page for :mod:`Tix`. This includes links to additional documentation
and downloads.
`Tix Man Pages <https://tix.sourceforge.net/dist/current/man/>`_
On-line version of the man pages and reference material.
`Tix Programming Guide <https://tix.sourceforge.net/dist/current/docs/tix-book/tix.book.html>`_
On-line version of the programmer's reference material.
`Tix Development Applications <https://tix.sourceforge.net/Tixapps/src/Tide.html>`_
Tix applications for development of Tix and Tkinter programs. Tide applications
work under Tk or Tkinter, and include :program:`TixInspect`, an inspector to
remotely modify and debug Tix/Tk/Tkinter applications.
Using Tix
---------
.. class:: Tk(screenName=None, baseName=None, className='Tix')
Toplevel widget of Tix which represents mostly the main window of an
application. It has an associated Tcl interpreter.
Classes in the :mod:`tkinter.tix` module subclasses the classes in the
:mod:`tkinter`. The former imports the latter, so to use :mod:`tkinter.tix`
with Tkinter, all you need to do is to import one module. In general, you
can just import :mod:`tkinter.tix`, and replace the toplevel call to
:class:`tkinter.Tk` with :class:`tix.Tk`::
from tkinter import tix
from tkinter.constants import *
root = tix.Tk()
To use :mod:`tkinter.tix`, you must have the Tix widgets installed, usually
alongside your installation of the Tk widgets. To test your installation, try
the following::
from tkinter import tix
root = tix.Tk()
root.tk.eval('package require Tix')
Tix Widgets
-----------
`Tix <https://tix.sourceforge.net/dist/current/man/html/TixCmd/TixIntro.htm>`_
introduces over 40 widget classes to the :mod:`tkinter` repertoire.
Basic Widgets
^^^^^^^^^^^^^
.. class:: Balloon()
A `Balloon
<https://tix.sourceforge.net/dist/current/man/html/TixCmd/tixBalloon.htm>`_ that
pops up over a widget to provide help. When the user moves the cursor inside a
widget to which a Balloon widget has been bound, a small pop-up window with a
descriptive message will be shown on the screen.
.. Python Demo of:
.. \ulink{Balloon}{https://tix.sourceforge.net/dist/current/demos/samples/Balloon.tcl}
.. class:: ButtonBox()
The `ButtonBox
<https://tix.sourceforge.net/dist/current/man/html/TixCmd/tixButtonBox.htm>`_
widget creates a box of buttons, such as is commonly used for ``Ok Cancel``.
.. Python Demo of:
.. \ulink{ButtonBox}{https://tix.sourceforge.net/dist/current/demos/samples/BtnBox.tcl}
.. class:: ComboBox()
The `ComboBox
<https://tix.sourceforge.net/dist/current/man/html/TixCmd/tixComboBox.htm>`_
widget is similar to the combo box control in MS Windows. The user can select a
choice by either typing in the entry subwidget or selecting from the listbox
subwidget.
.. Python Demo of:
.. \ulink{ComboBox}{https://tix.sourceforge.net/dist/current/demos/samples/ComboBox.tcl}
.. class:: Control()
The `Control
<https://tix.sourceforge.net/dist/current/man/html/TixCmd/tixControl.htm>`_
widget is also known as the :class:`SpinBox` widget. The user can adjust the
value by pressing the two arrow buttons or by entering the value directly into
the entry. The new value will be checked against the user-defined upper and
lower limits.
.. Python Demo of:
.. \ulink{Control}{https://tix.sourceforge.net/dist/current/demos/samples/Control.tcl}
.. class:: LabelEntry()
The `LabelEntry
<https://tix.sourceforge.net/dist/current/man/html/TixCmd/tixLabelEntry.htm>`_
widget packages an entry widget and a label into one mega widget. It can
be used to simplify the creation of "entry-form" type of interface.
.. Python Demo of:
.. \ulink{LabelEntry}{https://tix.sourceforge.net/dist/current/demos/samples/LabEntry.tcl}
.. class:: LabelFrame()
The `LabelFrame
<https://tix.sourceforge.net/dist/current/man/html/TixCmd/tixLabelFrame.htm>`_
widget packages a frame widget and a label into one mega widget. To create
widgets inside a LabelFrame widget, one creates the new widgets relative to the
:attr:`frame` subwidget and manage them inside the :attr:`frame` subwidget.
.. Python Demo of:
.. \ulink{LabelFrame}{https://tix.sourceforge.net/dist/current/demos/samples/LabFrame.tcl}
.. class:: Meter()
The `Meter
<https://tix.sourceforge.net/dist/current/man/html/TixCmd/tixMeter.htm>`_ widget
can be used to show the progress of a background job which may take a long time
to execute.
.. Python Demo of:
.. \ulink{Meter}{https://tix.sourceforge.net/dist/current/demos/samples/Meter.tcl}
.. class:: OptionMenu()
The `OptionMenu
<https://tix.sourceforge.net/dist/current/man/html/TixCmd/tixOptionMenu.htm>`_
creates a menu button of options.
.. Python Demo of:
.. \ulink{OptionMenu}{https://tix.sourceforge.net/dist/current/demos/samples/OptMenu.tcl}
.. class:: PopupMenu()
The `PopupMenu
<https://tix.sourceforge.net/dist/current/man/html/TixCmd/tixPopupMenu.htm>`_
widget can be used as a replacement of the ``tk_popup`` command. The advantage
of the :mod:`Tix` :class:`PopupMenu` widget is it requires less application code
to manipulate.
.. Python Demo of:
.. \ulink{PopupMenu}{https://tix.sourceforge.net/dist/current/demos/samples/PopMenu.tcl}
.. class:: Select()
The `Select
<https://tix.sourceforge.net/dist/current/man/html/TixCmd/tixSelect.htm>`_ widget
is a container of button subwidgets. It can be used to provide radio-box or
check-box style of selection options for the user.
.. Python Demo of:
.. \ulink{Select}{https://tix.sourceforge.net/dist/current/demos/samples/Select.tcl}
.. class:: StdButtonBox()
The `StdButtonBox
<https://tix.sourceforge.net/dist/current/man/html/TixCmd/tixStdButtonBox.htm>`_
widget is a group of standard buttons for Motif-like dialog boxes.
.. Python Demo of:
.. \ulink{StdButtonBox}{https://tix.sourceforge.net/dist/current/demos/samples/StdBBox.tcl}
File Selectors
^^^^^^^^^^^^^^
.. class:: DirList()
The `DirList
<https://tix.sourceforge.net/dist/current/man/html/TixCmd/tixDirList.htm>`_
widget displays a list view of a directory, its previous directories and its
sub-directories. The user can choose one of the directories displayed in the
list or change to another directory.
.. Python Demo of:
.. \ulink{DirList}{https://tix.sourceforge.net/dist/current/demos/samples/DirList.tcl}
.. class:: DirTree()
The `DirTree
<https://tix.sourceforge.net/dist/current/man/html/TixCmd/tixDirTree.htm>`_
widget displays a tree view of a directory, its previous directories and its
sub-directories. The user can choose one of the directories displayed in the
list or change to another directory.
.. Python Demo of:
.. \ulink{DirTree}{https://tix.sourceforge.net/dist/current/demos/samples/DirTree.tcl}
.. class:: DirSelectDialog()
The `DirSelectDialog
<https://tix.sourceforge.net/dist/current/man/html/TixCmd/tixDirSelectDialog.htm>`_
widget presents the directories in the file system in a dialog window. The user
can use this dialog window to navigate through the file system to select the
desired directory.
.. Python Demo of:
.. \ulink{DirSelectDialog}{https://tix.sourceforge.net/dist/current/demos/samples/DirDlg.tcl}
.. class:: DirSelectBox()
The :class:`DirSelectBox` is similar to the standard Motif(TM)
directory-selection box. It is generally used for the user to choose a
directory. DirSelectBox stores the directories mostly recently selected into
a ComboBox widget so that they can be quickly selected again.
.. class:: ExFileSelectBox()
The `ExFileSelectBox
<https://tix.sourceforge.net/dist/current/man/html/TixCmd/tixExFileSelectBox.htm>`_
widget is usually embedded in a tixExFileSelectDialog widget. It provides a
convenient method for the user to select files. The style of the
:class:`ExFileSelectBox` widget is very similar to the standard file dialog on
MS Windows 3.1.
.. Python Demo of:
.. \ulink{ExFileSelectDialog}{https://tix.sourceforge.net/dist/current/demos/samples/EFileDlg.tcl}
.. class:: FileSelectBox()
The `FileSelectBox
<https://tix.sourceforge.net/dist/current/man/html/TixCmd/tixFileSelectBox.htm>`_
is similar to the standard Motif(TM) file-selection box. It is generally used
for the user to choose a file. FileSelectBox stores the files mostly recently
selected into a :class:`ComboBox` widget so that they can be quickly selected
again.
.. Python Demo of:
.. \ulink{FileSelectDialog}{https://tix.sourceforge.net/dist/current/demos/samples/FileDlg.tcl}
.. class:: FileEntry()
The `FileEntry
<https://tix.sourceforge.net/dist/current/man/html/TixCmd/tixFileEntry.htm>`_
widget can be used to input a filename. The user can type in the filename
manually. Alternatively, the user can press the button widget that sits next to
the entry, which will bring up a file selection dialog.
.. Python Demo of:
.. \ulink{FileEntry}{https://tix.sourceforge.net/dist/current/demos/samples/FileEnt.tcl}
Hierarchical ListBox
^^^^^^^^^^^^^^^^^^^^
.. class:: HList()
The `HList
<https://tix.sourceforge.net/dist/current/man/html/TixCmd/tixHList.htm>`_ widget
can be used to display any data that have a hierarchical structure, for example,
file system directory trees. The list entries are indented and connected by
branch lines according to their places in the hierarchy.
.. Python Demo of:
.. \ulink{HList}{https://tix.sourceforge.net/dist/current/demos/samples/HList1.tcl}
.. class:: CheckList()
The `CheckList
<https://tix.sourceforge.net/dist/current/man/html/TixCmd/tixCheckList.htm>`_
widget displays a list of items to be selected by the user. CheckList acts
similarly to the Tk checkbutton or radiobutton widgets, except it is capable of
handling many more items than checkbuttons or radiobuttons.
.. Python Demo of:
.. \ulink{ CheckList}{https://tix.sourceforge.net/dist/current/demos/samples/ChkList.tcl}
.. Python Demo of:
.. \ulink{ScrolledHList (1)}{https://tix.sourceforge.net/dist/current/demos/samples/SHList.tcl}
.. Python Demo of:
.. \ulink{ScrolledHList (2)}{https://tix.sourceforge.net/dist/current/demos/samples/SHList2.tcl}
.. class:: Tree()
The `Tree
<https://tix.sourceforge.net/dist/current/man/html/TixCmd/tixTree.htm>`_ widget
can be used to display hierarchical data in a tree form. The user can adjust the
view of the tree by opening or closing parts of the tree.
.. Python Demo of:
.. \ulink{Tree}{https://tix.sourceforge.net/dist/current/demos/samples/Tree.tcl}
.. Python Demo of:
.. \ulink{Tree (Dynamic)}{https://tix.sourceforge.net/dist/current/demos/samples/DynTree.tcl}
Tabular ListBox
^^^^^^^^^^^^^^^
.. class:: TList()
The `TList
<https://tix.sourceforge.net/dist/current/man/html/TixCmd/tixTList.htm>`_ widget
can be used to display data in a tabular format. The list entries of a
:class:`TList` widget are similar to the entries in the Tk listbox widget. The
main differences are (1) the :class:`TList` widget can display the list entries
in a two dimensional format and (2) you can use graphical images as well as
multiple colors and fonts for the list entries.
.. Python Demo of:
.. \ulink{ScrolledTList (1)}{https://tix.sourceforge.net/dist/current/demos/samples/STList1.tcl}
.. Python Demo of:
.. \ulink{ScrolledTList (2)}{https://tix.sourceforge.net/dist/current/demos/samples/STList2.tcl}
.. Grid has yet to be added to Python
.. \subsubsection{Grid Widget}
.. Python Demo of:
.. \ulink{Simple Grid}{https://tix.sourceforge.net/dist/current/demos/samples/SGrid0.tcl}
.. Python Demo of:
.. \ulink{ScrolledGrid}{https://tix.sourceforge.net/dist/current/demos/samples/SGrid1.tcl}
.. Python Demo of:
.. \ulink{Editable Grid}{https://tix.sourceforge.net/dist/current/demos/samples/EditGrid.tcl}
Manager Widgets
^^^^^^^^^^^^^^^
.. class:: PanedWindow()
The `PanedWindow
<https://tix.sourceforge.net/dist/current/man/html/TixCmd/tixPanedWindow.htm>`_
widget allows the user to interactively manipulate the sizes of several panes.
The panes can be arranged either vertically or horizontally. The user changes
the sizes of the panes by dragging the resize handle between two panes.
.. Python Demo of:
.. \ulink{PanedWindow}{https://tix.sourceforge.net/dist/current/demos/samples/PanedWin.tcl}
.. class:: ListNoteBook()
The `ListNoteBook
<https://tix.sourceforge.net/dist/current/man/html/TixCmd/tixListNoteBook.htm>`_
widget is very similar to the :class:`TixNoteBook` widget: it can be used to
display many windows in a limited space using a notebook metaphor. The notebook
is divided into a stack of pages (windows). At one time only one of these pages
can be shown. The user can navigate through these pages by choosing the name of
the desired page in the :attr:`hlist` subwidget.
.. Python Demo of:
.. \ulink{ListNoteBook}{https://tix.sourceforge.net/dist/current/demos/samples/ListNBK.tcl}
.. class:: NoteBook()
The `NoteBook
<https://tix.sourceforge.net/dist/current/man/html/TixCmd/tixNoteBook.htm>`_
widget can be used to display many windows in a limited space using a notebook
metaphor. The notebook is divided into a stack of pages. At one time only one of
these pages can be shown. The user can navigate through these pages by choosing
the visual "tabs" at the top of the NoteBook widget.
.. Python Demo of:
.. \ulink{NoteBook}{https://tix.sourceforge.net/dist/current/demos/samples/NoteBook.tcl}
.. \subsubsection{Scrolled Widgets}
.. Python Demo of:
.. \ulink{ScrolledListBox}{https://tix.sourceforge.net/dist/current/demos/samples/SListBox.tcl}
.. Python Demo of:
.. \ulink{ScrolledText}{https://tix.sourceforge.net/dist/current/demos/samples/SText.tcl}
.. Python Demo of:
.. \ulink{ScrolledWindow}{https://tix.sourceforge.net/dist/current/demos/samples/SWindow.tcl}
.. Python Demo of:
.. \ulink{Canvas Object View}{https://tix.sourceforge.net/dist/current/demos/samples/CObjView.tcl}
Image Types
^^^^^^^^^^^
The :mod:`tkinter.tix` module adds:
* `pixmap <https://tix.sourceforge.net/dist/current/man/html/TixCmd/pixmap.htm>`_
capabilities to all :mod:`tkinter.tix` and :mod:`tkinter` widgets to create
color images from XPM files.
.. Python Demo of:
.. \ulink{XPM Image In Button}{https://tix.sourceforge.net/dist/current/demos/samples/Xpm.tcl}
.. Python Demo of:
.. \ulink{XPM Image In Menu}{https://tix.sourceforge.net/dist/current/demos/samples/Xpm1.tcl}
* `Compound
<https://tix.sourceforge.net/dist/current/man/html/TixCmd/compound.htm>`_ image
types can be used to create images that consists of multiple horizontal lines;
each line is composed of a series of items (texts, bitmaps, images or spaces)
arranged from left to right. For example, a compound image can be used to
display a bitmap and a text string simultaneously in a Tk :class:`Button`
widget.
.. Python Demo of:
.. \ulink{Compound Image In Buttons}{https://tix.sourceforge.net/dist/current/demos/samples/CmpImg.tcl}
.. Python Demo of:
.. \ulink{Compound Image In NoteBook}{https://tix.sourceforge.net/dist/current/demos/samples/CmpImg2.tcl}
.. Python Demo of:
.. \ulink{Compound Image Notebook Color Tabs}{https://tix.sourceforge.net/dist/current/demos/samples/CmpImg4.tcl}
.. Python Demo of:
.. \ulink{Compound Image Icons}{https://tix.sourceforge.net/dist/current/demos/samples/CmpImg3.tcl}
Miscellaneous Widgets
^^^^^^^^^^^^^^^^^^^^^
.. class:: InputOnly()
The `InputOnly
<https://tix.sourceforge.net/dist/current/man/html/TixCmd/tixInputOnly.htm>`_
widgets are to accept inputs from the user, which can be done with the ``bind``
command (Unix only).
Form Geometry Manager
^^^^^^^^^^^^^^^^^^^^^
In addition, :mod:`tkinter.tix` augments :mod:`tkinter` by providing:
.. class:: Form()
The `Form
<https://tix.sourceforge.net/dist/current/man/html/TixCmd/tixForm.htm>`_ geometry
manager based on attachment rules for all Tk widgets.
Tix Commands
------------
.. class:: tixCommand()
The `tix commands
<https://tix.sourceforge.net/dist/current/man/html/TixCmd/tix.htm>`_ provide
access to miscellaneous elements of :mod:`Tix`'s internal state and the
:mod:`Tix` application context. Most of the information manipulated by these
methods pertains to the application as a whole, or to a screen or display,
rather than to a particular window.
To view the current settings, the common usage is::
from tkinter import tix
root = tix.Tk()
print(root.tix_configure())
.. method:: tixCommand.tix_configure(cnf=None, **kw)
Query or modify the configuration options of the Tix application context. If no
option is specified, returns a dictionary all of the available options. If
option is specified with no value, then the method returns a list describing the
one named option (this list will be identical to the corresponding sublist of
the value returned if no option is specified). If one or more option-value
pairs are specified, then the method modifies the given option(s) to have the
given value(s); in this case the method returns an empty string. Option may be
any of the configuration options.
.. method:: tixCommand.tix_cget(option)
Returns the current value of the configuration option given by *option*. Option
may be any of the configuration options.
.. method:: tixCommand.tix_getbitmap(name)
Locates a bitmap file of the name ``name.xpm`` or ``name`` in one of the bitmap
directories (see the :meth:`tix_addbitmapdir` method). By using
:meth:`tix_getbitmap`, you can avoid hard coding the pathnames of the bitmap
files in your application. When successful, it returns the complete pathname of
the bitmap file, prefixed with the character ``@``. The returned value can be
used to configure the ``bitmap`` option of the Tk and Tix widgets.
.. method:: tixCommand.tix_addbitmapdir(directory)
Tix maintains a list of directories under which the :meth:`tix_getimage` and
:meth:`tix_getbitmap` methods will search for image files. The standard bitmap
directory is :file:`$TIX_LIBRARY/bitmaps`. The :meth:`tix_addbitmapdir` method
adds *directory* into this list. By using this method, the image files of an
applications can also be located using the :meth:`tix_getimage` or
:meth:`tix_getbitmap` method.
.. method:: tixCommand.tix_filedialog([dlgclass])
Returns the file selection dialog that may be shared among different calls from
this application. This method will create a file selection dialog widget when
it is called the first time. This dialog will be returned by all subsequent
calls to :meth:`tix_filedialog`. An optional dlgclass parameter can be passed
as a string to specified what type of file selection dialog widget is desired.
Possible options are ``tix``, ``FileSelectDialog`` or ``tixExFileSelectDialog``.
.. method:: tixCommand.tix_getimage(self, name)
Locates an image file of the name :file:`name.xpm`, :file:`name.xbm` or
:file:`name.ppm` in one of the bitmap directories (see the
:meth:`tix_addbitmapdir` method above). If more than one file with the same name
(but different extensions) exist, then the image type is chosen according to the
depth of the X display: xbm images are chosen on monochrome displays and color
images are chosen on color displays. By using :meth:`tix_getimage`, you can
avoid hard coding the pathnames of the image files in your application. When
successful, this method returns the name of the newly created image, which can
be used to configure the ``image`` option of the Tk and Tix widgets.
.. method:: tixCommand.tix_option_get(name)
Gets the options maintained by the Tix scheme mechanism.
.. method:: tixCommand.tix_resetoptions(newScheme, newFontSet[, newScmPrio])
Resets the scheme and fontset of the Tix application to *newScheme* and
*newFontSet*, respectively. This affects only those widgets created after this
call. Therefore, it is best to call the resetoptions method before the creation
of any widgets in a Tix application.
The optional parameter *newScmPrio* can be given to reset the priority level of
the Tk options set by the Tix schemes.
Because of the way Tk handles the X option database, after Tix has been has
imported and inited, it is not possible to reset the color schemes and font sets
using the :meth:`tix_config` method. Instead, the :meth:`tix_resetoptions`
method must be used.

View File

@ -215,7 +215,6 @@ Doc/library/threading.rst
Doc/library/time.rst Doc/library/time.rst
Doc/library/tkinter.rst Doc/library/tkinter.rst
Doc/library/tkinter.scrolledtext.rst Doc/library/tkinter.scrolledtext.rst
Doc/library/tkinter.tix.rst
Doc/library/tkinter.ttk.rst Doc/library/tkinter.ttk.rst
Doc/library/traceback.rst Doc/library/traceback.rst
Doc/library/tty.rst Doc/library/tty.rst

View File

@ -1555,7 +1555,7 @@ complete list of changes, or look through the CVS logs for all the details.
# [0.36831796169281006, 0.37441694736480713, 0.35304892063140869] # [0.36831796169281006, 0.37441694736480713, 0.35304892063140869]
# [0.17574405670166016, 0.18193507194519043, 0.17565798759460449] # [0.17574405670166016, 0.18193507194519043, 0.17565798759460449]
* The :mod:`Tix` module has received various bug fixes and updates for the * The :mod:`!Tix` module has received various bug fixes and updates for the
current version of the Tix package. current version of the Tix package.
* The :mod:`Tkinter` module now works with a thread-enabled version of Tcl. * The :mod:`Tkinter` module now works with a thread-enabled version of Tcl.

View File

@ -256,6 +256,10 @@ Removed
or `python-magic <https://pypi.org/project/python-magic/>`_ instead. or `python-magic <https://pypi.org/project/python-magic/>`_ instead.
(Contributed by Victor Stinner in :gh:`104773`.) (Contributed by Victor Stinner in :gh:`104773`.)
* Remove the :mod:`!tkinter.tix` module, deprecated in Python 3.6. The
third-party Tix library which the module wrapped is unmaintained.
(Contributed by Zachary Ware in :gh:`75552`.)
Porting to Python 3.13 Porting to Python 3.13
====================== ======================

View File

@ -2049,7 +2049,7 @@ of OpenSSL. Other features are deprecated in favor of a different API.
tkinter tkinter
~~~~~~~ ~~~~~~~
The :mod:`tkinter.tix` module is now deprecated. :mod:`tkinter` users The :mod:`!tkinter.tix` module is now deprecated. :mod:`tkinter` users
should use :mod:`tkinter.ttk` instead. should use :mod:`tkinter.ttk` instead.
.. _whatsnew36-venv: .. _whatsnew36-venv:

View File

@ -22,7 +22,6 @@ IMPORT_MAPPING = {
'tkMessageBox': 'tkinter.messagebox', 'tkMessageBox': 'tkinter.messagebox',
'ScrolledText': 'tkinter.scrolledtext', 'ScrolledText': 'tkinter.scrolledtext',
'Tkconstants': 'tkinter.constants', 'Tkconstants': 'tkinter.constants',
'Tix': 'tkinter.tix',
'ttk': 'tkinter.ttk', 'ttk': 'tkinter.ttk',
'Tkinter': 'tkinter', 'Tkinter': 'tkinter',
'markupbase': '_markupbase', 'markupbase': '_markupbase',

View File

@ -296,7 +296,6 @@ def collect_os(info_add):
"TEMP", "TEMP",
"TERM", "TERM",
"TILE_LIBRARY", "TILE_LIBRARY",
"TIX_LIBRARY",
"TMP", "TMP",
"TMPDIR", "TMPDIR",
"TRAVIS", "TRAVIS",

View File

@ -1,40 +0,0 @@
import sys
import unittest
from test import support
from test.support import import_helper
from test.support import check_sanitizer
if check_sanitizer(address=True, memory=True):
raise unittest.SkipTest("Tests involving libX11 can SEGFAULT on ASAN/MSAN builds")
# Skip this test if the _tkinter module wasn't built.
_tkinter = import_helper.import_module('_tkinter')
# Skip test if tk cannot be initialized.
support.requires('gui')
# Suppress the deprecation warning
tix = import_helper.import_module('tkinter.tix', deprecated=True)
from tkinter import TclError
class TestTix(unittest.TestCase):
def setUp(self):
try:
self.root = tix.Tk()
except TclError:
if sys.platform.startswith('win'):
self.fail('Tix should always be available on Windows')
self.skipTest('Tix not available')
else:
self.addCleanup(self.root.destroy)
def test_tix_available(self):
# this test is just here to make setUp run
pass
if __name__ == '__main__':
unittest.main()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
Removed the ``tkinter.tix`` module, deprecated since Python 3.6.

View File

@ -57,7 +57,6 @@ if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1t
set libraries=%libraries% sqlite-3.42.0.0 set libraries=%libraries% sqlite-3.42.0.0
if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.13.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.13.0
if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.13.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.13.0
if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tix-8.4.3.6
set libraries=%libraries% xz-5.2.5 set libraries=%libraries% xz-5.2.5
set libraries=%libraries% zlib-1.2.13 set libraries=%libraries% zlib-1.2.13

View File

@ -48,12 +48,9 @@ call "%PCBUILD%\get_externals.bat" --tkinter-src %ORG_SETTING%
%MSBUILD% "%PCBUILD%\tcl.vcxproj" /p:Configuration=Release /p:Platform=Win32 %MSBUILD% "%PCBUILD%\tcl.vcxproj" /p:Configuration=Release /p:Platform=Win32
%MSBUILD% "%PCBUILD%\tk.vcxproj" /p:Configuration=Release /p:Platform=Win32 %MSBUILD% "%PCBUILD%\tk.vcxproj" /p:Configuration=Release /p:Platform=Win32
%MSBUILD% "%PCBUILD%\tix.vcxproj" /p:Configuration=Release /p:Platform=Win32
%MSBUILD% "%PCBUILD%\tcl.vcxproj" /p:Configuration=Release /p:Platform=x64 %MSBUILD% "%PCBUILD%\tcl.vcxproj" /p:Configuration=Release /p:Platform=x64
%MSBUILD% "%PCBUILD%\tk.vcxproj" /p:Configuration=Release /p:Platform=x64 %MSBUILD% "%PCBUILD%\tk.vcxproj" /p:Configuration=Release /p:Platform=x64
%MSBUILD% "%PCBUILD%\tix.vcxproj" /p:Configuration=Release /p:Platform=x64
%MSBUILD% "%PCBUILD%\tcl.vcxproj" /p:Configuration=Release /p:Platform=ARM64 %MSBUILD% "%PCBUILD%\tcl.vcxproj" /p:Configuration=Release /p:Platform=ARM64
%MSBUILD% "%PCBUILD%\tk.vcxproj" /p:Configuration=Release /p:Platform=ARM64 %MSBUILD% "%PCBUILD%\tk.vcxproj" /p:Configuration=Release /p:Platform=ARM64
%MSBUILD% "%PCBUILD%\tix.vcxproj" /p:Configuration=Release /p:Platform=ARM64

View File

@ -282,7 +282,7 @@ The property files used are:
* python (versions, directories and build names) * python (versions, directories and build names)
* pyproject (base settings for all projects) * pyproject (base settings for all projects)
* openssl (used by projects dependent upon OpenSSL) * openssl (used by projects dependent upon OpenSSL)
* tcltk (used by _tkinter, tcl, tk and tix projects) * tcltk (used by _tkinter, tcl, and tk projects)
The pyproject property file defines all of the build settings for each The pyproject property file defines all of the build settings for each
project, with some projects overriding certain specific values. The GUI project, with some projects overriding certain specific values. The GUI

View File

@ -107,8 +107,7 @@
$(opensslOutDir)LICENSE; $(opensslOutDir)LICENSE;
$(libffiDir)LICENSE;" /> $(libffiDir)LICENSE;" />
<_LicenseSources Include="$(tcltkDir)tcllicense.terms; <_LicenseSources Include="$(tcltkDir)tcllicense.terms;
$(tcltkDir)tklicense.terms; $(tcltkDir)tklicense.terms" Condition="$(IncludeTkinter)" />
$(tcltkDir)tixlicense.terms" Condition="$(IncludeTkinter)" />
</ItemGroup> </ItemGroup>
<Target Name="_RegenTestFrozenmain" Inputs="@(_TestFrozenSources)" Outputs="@(_TestFrozenOutputs)" <Target Name="_RegenTestFrozenmain" Inputs="@(_TestFrozenSources)" Outputs="@(_TestFrozenOutputs)"

View File

@ -4,7 +4,6 @@
<PropertyGroup> <PropertyGroup>
<TclVersion Condition="$(TclVersion) == ''">8.6.13.0</TclVersion> <TclVersion Condition="$(TclVersion) == ''">8.6.13.0</TclVersion>
<TkVersion Condition="$(TkVersion) == ''">$(TclVersion)</TkVersion> <TkVersion Condition="$(TkVersion) == ''">$(TclVersion)</TkVersion>
<TixVersion Condition="$(TixVersion) == ''">8.4.3.6</TixVersion>
<TclMajorVersion>$([System.Version]::Parse($(TclVersion)).Major)</TclMajorVersion> <TclMajorVersion>$([System.Version]::Parse($(TclVersion)).Major)</TclMajorVersion>
<TclMinorVersion>$([System.Version]::Parse($(TclVersion)).Minor)</TclMinorVersion> <TclMinorVersion>$([System.Version]::Parse($(TclVersion)).Minor)</TclMinorVersion>
<TclPatchLevel>$([System.Version]::Parse($(TclVersion)).Build)</TclPatchLevel> <TclPatchLevel>$([System.Version]::Parse($(TclVersion)).Build)</TclPatchLevel>
@ -13,13 +12,8 @@
<TkMinorVersion>$([System.Version]::Parse($(TkVersion)).Minor)</TkMinorVersion> <TkMinorVersion>$([System.Version]::Parse($(TkVersion)).Minor)</TkMinorVersion>
<TkPatchLevel>$([System.Version]::Parse($(TkVersion)).Build)</TkPatchLevel> <TkPatchLevel>$([System.Version]::Parse($(TkVersion)).Build)</TkPatchLevel>
<TkRevision>$([System.Version]::Parse($(TkVersion)).Revision)</TkRevision> <TkRevision>$([System.Version]::Parse($(TkVersion)).Revision)</TkRevision>
<TixMajorVersion>$([System.Version]::Parse($(TixVersion)).Major)</TixMajorVersion>
<TixMinorVersion>$([System.Version]::Parse($(TixVersion)).Minor)</TixMinorVersion>
<TixPatchLevel>$([System.Version]::Parse($(TixVersion)).Build)</TixPatchLevel>
<TixRevision>$([System.Version]::Parse($(TixVersion)).Revision)</TixRevision>
<tclDir Condition="$(tclDir) == ''">$(ExternalsDir)tcl-core-$(TclVersion)\</tclDir> <tclDir Condition="$(tclDir) == ''">$(ExternalsDir)tcl-core-$(TclVersion)\</tclDir>
<tkDir Condition="$(tkDir) == ''">$(ExternalsDir)tk-$(TkVersion)\</tkDir> <tkDir Condition="$(tkDir) == ''">$(ExternalsDir)tk-$(TkVersion)\</tkDir>
<tixDir Condition="$(tixDir) == ''">$(ExternalsDir)tix-$(TixVersion)\</tixDir>
<tcltkDir Condition="$(tcltkDir) == ''">$(ExternalsDir)tcltk-$(TclVersion)\$(ArchName)\</tcltkDir> <tcltkDir Condition="$(tcltkDir) == ''">$(ExternalsDir)tcltk-$(TclVersion)\$(ArchName)\</tcltkDir>
<tclWin32Exe Condition="$(Platform) == 'Win32'">$(tcltkDir)\bin\tclsh$(TclMajorVersion)$(TclMinorVersion)t.exe</tclWin32Exe> <tclWin32Exe Condition="$(Platform) == 'Win32'">$(tcltkDir)\bin\tclsh$(TclMajorVersion)$(TclMinorVersion)t.exe</tclWin32Exe>
<tclWin32Exe Condition="$(Platform) != 'Win32'">$(tcltkDir)\..\win32\bin\tclsh$(TclMajorVersion)$(TclMinorVersion)t.exe</tclWin32Exe> <tclWin32Exe Condition="$(Platform) != 'Win32'">$(tcltkDir)\..\win32\bin\tclsh$(TclMajorVersion)$(TclMinorVersion)t.exe</tclWin32Exe>
@ -31,8 +25,6 @@
<tkDLLName>tk$(TkMajorVersion)$(TkMinorVersion)t$(TclDebugExt).dll</tkDLLName> <tkDLLName>tk$(TkMajorVersion)$(TkMinorVersion)t$(TclDebugExt).dll</tkDLLName>
<tkLibName>tk$(TkMajorVersion)$(TkMinorVersion)t$(TclDebugExt).lib</tkLibName> <tkLibName>tk$(TkMajorVersion)$(TkMinorVersion)t$(TclDebugExt).lib</tkLibName>
<tclZlibDLLName>zlib1.dll</tclZlibDLLName> <tclZlibDLLName>zlib1.dll</tclZlibDLLName>
<tixDLLName>tix$(TixMajorVersion)$(TixMinorVersion)$(TclDebugExt).dll</tixDLLName>
<tixDLLPath>$(tcltkDir)lib\tix$(TixMajorVersion).$(TixMinorVersion).$(TixPatchLevel)\$(tixDLLName)</tixDLLPath>
<tcltkLib>$(tcltkDir)lib\tcl$(TclMajorVersion)$(TclMinorVersion)t$(TclDebugExt).lib;$(tcltkDir)lib\tk$(TkMajorVersion)$(TkMinorVersion)t$(TclDebugExt).lib</tcltkLib> <tcltkLib>$(tcltkDir)lib\tcl$(TclMajorVersion)$(TclMinorVersion)t$(TclDebugExt).lib;$(tcltkDir)lib\tk$(TkMajorVersion)$(TkMinorVersion)t$(TclDebugExt).lib</tcltkLib>
<TclMachine>IX86</TclMachine> <TclMachine>IX86</TclMachine>
<TclMachine Condition="'$(Platform)' == 'x64'">AMD64</TclMachine> <TclMachine Condition="'$(Platform)' == 'x64'">AMD64</TclMachine>

View File

@ -1,101 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGInstrument|Win32">
<Configuration>PGInstrument</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGInstrument|x64">
<Configuration>PGInstrument</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGUpdate|Win32">
<Configuration>PGUpdate</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGUpdate|x64">
<Configuration>PGUpdate</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}</ProjectGuid>
<RootNamespace>tix</RootNamespace>
<SupportSigning>true</SupportSigning>
</PropertyGroup>
<Import Project="python.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<Import Project="tcltk.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<OutDir>$(tcltkDir)</OutDir>
<TargetPath>$(tixDLLPath)</TargetPath>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<PropertyGroup>
<TixDirs>BUILDDIRTOP="$(BuildDirTop)" TCL_DIR="$(tclDir.TrimEnd(`\`))" TK_DIR="$(tkDir.TrimEnd(`\`))" INSTALL_DIR="$(OutDir.TrimEnd(`\`))" TCLSH_EXE="$(tclWin32Exe)"</TixDirs>
<DebugFlags Condition="'$(Configuration)' == 'Debug'">DEBUG=1 NODEBUG=0 TCL_DBGX=g TK_DBGX=g</DebugFlags>
<DebugFlags Condition="'$(Configuration)' != 'Debug'">DEBUG=0 NODEBUG=1</DebugFlags>
<CFlags>-c -W3 -nologo -MD -wd4028 -wd4090 -wd4244 -wd4267 -wd4312</CFlags>
<NMakeBuildCommandLine>setlocal
set VCINSTALLDIR=$(VCInstallDir)
cd /D "$(tixDir)win"
nmake /nologo -f makefile.vc MACHINE=$(TclMachine) cflags="$(CFlags)" $(DebugFlags) $(TclShortVersions) $(TixDirs) all install
copy /Y ..\license.terms "$(OutDir)\tixlicense.terms"
</NMakeBuildCommandLine>
<NMakeCleanCommandLine>rmdir /q/s "$(OutDir.TrimEnd(`\`))"</NMakeCleanCommandLine>
</PropertyGroup>
<Target Name="SignFiles" AfterTargets="Build" Condition="$(_SignCommand) != ''">
<ItemGroup>
<FilesToSign Include="$(OutDir)\bin\*.exe" />
<FilesToSign Include="$(OutDir)\bin\*.dll" />
</ItemGroup>
<Exec Command="$(_SignCommand) &quot;%(FilesToSign.FullPath)&quot;" ContinueOnError="true" />
</Target>
<ItemGroup>
<ProjectReference Include="tcl.vcxproj">
<Project>{b5fd6f1d-129e-4bff-9340-03606fac7283}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="tk.vcxproj">
<Project>{7e85eccf-a72c-4da4-9e52-884508e80ba1}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Target Name="Clean" />
<Target Name="CleanAll">
<RemoveDir Directories="$(OutDir)" />
<RemoveDir Directories="$(IntDir)" />
</Target>
<Target Name="ResolveAssemblyReferences" />
</Project>

View File

@ -98,13 +98,13 @@ use Tkinter without a Tcl/Tk installation. The best way to ship a
frozen Tkinter program is to decide in advance where you are going frozen Tkinter program is to decide in advance where you are going
to place the Tcl and Tk library files in the distributed setup, and to place the Tcl and Tk library files in the distributed setup, and
then declare these directories in your frozen Python program using then declare these directories in your frozen Python program using
the TCL_LIBRARY, TK_LIBRARY and TIX_LIBRARY environment variables. the TCL_LIBRARY and TK_LIBRARY environment variables.
For example, assume you will ship your frozen program in the directory For example, assume you will ship your frozen program in the directory
<root>/bin/windows-x86 and will place your Tcl library files <root>/bin/windows-x86 and will place your Tcl library files
in <root>/lib/tcl8.2 and your Tk library files in <root>/lib/tk8.2. Then in <root>/lib/tcl8.2 and your Tk library files in <root>/lib/tk8.2. Then
placing the following lines in your frozen Python script before importing placing the following lines in your frozen Python script before importing
Tkinter or Tix would set the environment correctly for Tcl/Tk/Tix: tkinter would set the environment correctly for Tcl/Tk:
import os import os
import os.path import os.path
@ -115,17 +115,14 @@ if sys.platform == "win32":
sys.path = ['', '..\\..\\lib\\python-2.0'] sys.path = ['', '..\\..\\lib\\python-2.0']
os.environ['TCL_LIBRARY'] = RootDir + '\\lib\\tcl8.2' os.environ['TCL_LIBRARY'] = RootDir + '\\lib\\tcl8.2'
os.environ['TK_LIBRARY'] = RootDir + '\\lib\\tk8.2' os.environ['TK_LIBRARY'] = RootDir + '\\lib\\tk8.2'
os.environ['TIX_LIBRARY'] = RootDir + '\\lib\\tix8.1'
elif sys.platform == "linux2": elif sys.platform == "linux2":
sys.path = ['', '../../lib/python-2.0'] sys.path = ['', '../../lib/python-2.0']
os.environ['TCL_LIBRARY'] = RootDir + '/lib/tcl8.2' os.environ['TCL_LIBRARY'] = RootDir + '/lib/tcl8.2'
os.environ['TK_LIBRARY'] = RootDir + '/lib/tk8.2' os.environ['TK_LIBRARY'] = RootDir + '/lib/tk8.2'
os.environ['TIX_LIBRARY'] = RootDir + '/lib/tix8.1'
elif sys.platform == "solaris": elif sys.platform == "solaris":
sys.path = ['', '../../lib/python-2.0'] sys.path = ['', '../../lib/python-2.0']
os.environ['TCL_LIBRARY'] = RootDir + '/lib/tcl8.2' os.environ['TCL_LIBRARY'] = RootDir + '/lib/tcl8.2'
os.environ['TK_LIBRARY'] = RootDir + '/lib/tk8.2' os.environ['TK_LIBRARY'] = RootDir + '/lib/tk8.2'
os.environ['TIX_LIBRARY'] = RootDir + '/lib/tix8.1'
This also adds <root>/lib/python-2.0 to your Python path This also adds <root>/lib/python-2.0 to your Python path
for any Python files such as _tkinter.pyd you may need. for any Python files such as _tkinter.pyd you may need.
@ -148,10 +145,9 @@ executable would be possible, in which the Tcl/Tk library files are
incorporated in a frozen Python module as string literals and written incorporated in a frozen Python module as string literals and written
to a temporary location when the program runs; this is currently left to a temporary location when the program runs; this is currently left
as an exercise for the reader. An easier approach is to freeze the as an exercise for the reader. An easier approach is to freeze the
Tcl/Tk/Tix code into the dynamic libraries using the Tcl ET code, Tcl/Tk code into the dynamic libraries using the Tcl ET code.
or the Tix Stand-Alone-Module code. Of course, you can also simply Of course, you can also simply require that Tcl/Tk is required on the
require that Tcl/Tk is required on the target installation, but be target installation, but be careful that the version corresponds.
careful that the version corresponds.
There are some caveats using frozen Tkinter applications: There are some caveats using frozen Tkinter applications:
Under Windows if you use the -s windows option, writing Under Windows if you use the -s windows option, writing

View File

@ -10,7 +10,7 @@ __version__ = '1.0.0'
import re import re
import sys import sys
from urllib.request import * from urllib.request import Request, urlopen
VERSION_RE = re.compile(r'(\d+\.\d+\.\d+)([A-Za-z_]+\d+)?$') VERSION_RE = re.compile(r'(\d+\.\d+\.\d+)([A-Za-z_]+\d+)?$')