pythondialog News
This page describes the main changes since pythondialog 2.12 in a form suitable for human consumption. For the full details, or for changes in older versions, you may refer to the Git repository (you can click on “History”, or clone the repository and use git log). Alternatively, you should be able to find a ChangeLog file in any release tarball.
Python 2 backport not supported anymore
As you should know, Python 2 reached its end of life on January 1, 2020. There used to be a backport of pythondialog for Python 2, but it is now unsupported. No updates or fixes will be provided for it anymore. For people still using Python 2, it is high time to switch to Python 3 (Python 3.0 was released in 2008...).
Main changes in version 3.5.3
The only change in version 3.5.3 is:
-
Switch to the new https-based URL: the pythondialog home page is now https://pythondialog.sourceforge.io/. The previous URL, which didn't use HTTPS, still works and automatically redirects to the new one.
Main changes in version 3.5.2
The main changes in version 3.5.2 are:
-
Improved support for the
--timeout
dialog option. -
Show use of
d.add_persistent_args(["--no-nl-expand"])
in examples. This should probably always be used in your code; the only reason why it is not enabled by default in pythondialog is to avoid breaking compatibility.
Main changes in version 3.5.1
The main changes in version 3.5.1 are:
-
The default used when the PATH environment variable is unset is now
"/bin:/usr/bin"
instead of":/bin:/usr/bin"
. This is relevant when thedialog
argument of theDialog
constructor contains no slash (/), which is the case by default. The benefit of this change is that in such a situation (PATH unset anddialog
argument containing no slash), the dialog-like program will not be searched in the current directory anymore (unless of course the current directory is /bin or /usr/bin). This is a much safer behavior; fortunately, the risky behavior only ever existed on bogus setups where the PATH environment variable is unset.Note that in this respect, we have been following what the GNU C Library (glibc) does for its
execvp()
function—the corresponding change in glibc happened in version 2.24, released in 2016. -
When a
Dialog
instance is created, it now immediately stores the result of callingos.path.realpath()
on the specified executable (which is searched using the PATH if thedialog
argument passed to the constructor contains no slash—cf. documentation of theDialog
constructor). This way, a pythondialog-based program can change its current directory after creating aDialog
instance without fearing that this might cause subsequentDialog
method calls to fail or to invoke an executable from a different directory (additionally,os.path.realpath()
resolves symbolic links). -
The Python 2 backport of pythondialog has been released for this version and should be on par with pythondialog 3.5.1 (this is why version 3.5.0 of the backport has been skipped). The packaging of the backport has been switched from distutils to setuptools too, just as was done in pythondialog 3.5.0 (see below). As a consequence, it is now available in wheel format. However, as said above, Python 2 is deprecated and the Python 2 backport of pythondialog is not supported anymore. Don't expect any further updates to it.
Main changes in version 3.5.0
The main change in version 3.5.0 is:
-
pythondialog's packaging has been switched from distutils to setuptools (this is the modern way, see the Python Packaging User Guide). Thanks to this change, pythondialog is now available in wheel format. The normal installation method using pip didn't change (see the INSTALL file for details).
The Python 2 backport of pythondialog has not been released for this version (version 3.5.1 will be the last one).
Main changes in version 3.4.0
The main changes in version 3.4.0 are:
-
The Python 2 backport has been updated to this version.
-
Add method
Dialog.editbox_str()
. This is a convenience wrapper aroundDialog.editbox()
that automatically creates and deletes a temporary file containing the initial box contents, which is passed as a string (Dialog.editbox()
needs it in a file). -
Add the
week_start
common option, mapped to dialog's--week-start
option (it is useful with the widget). The value may be an integer or a string (cf. dialog's manual page for more details).
Main changes in version 3.3.0
The main changes in version 3.3.0 are:
-
The Python 2 backport has been updated to this version.
-
Allow passing dialog arguments via a temporary file
In order to prevent information leak through the process table (which normally shows all commands executed by any user, along with their arguments), pythondialog can now write dialog arguments to a temporary file and call dialog with the
--file
option to point him to this temporary file, where it will read the “real” arguments (such as--msgbox
, box titles, messages to display in boxes, etc.). This new behavior is enabled by default starting from pythondialog 3.3.0 if the dialog version is 1.2-20150513 or later. TheDialog
class constructor accepts a new keyword-only argument,pass_args_via_file
, that allows one to explicitly choose whether to use the feature or not.Dialog.setup_debug()
offers a newexpand_file_opt
parameter to allow producing debug log files with full dialog commands as before, instead of dialog calls containing only one--file
option followed by a path to a temporary file.Similarly, examples/demo.py accepts a new option (
-E
,--debug-expand-file-opt
) to allow obtaining the same dialog commands as before in the file generated by--debug
(i.e., with the--file
options expanded instead of referring to the temporary files).Thanks to Bernd Geiser for the feature request that led to these improvements.
-
Bug fix in
Dialog._dialog_version_check()
(which is typically used to check whether a given widget is available in the selected dialog version): the message passed when raisingInadequateBackendVersion
had a hardcoded “the programbox widget” substring where it should have been using thefeature
parameter.
Main changes in version 3.2.2
The main changes in version 3.2.2 are:
-
The Python 2 backport has been updated to this version.
-
Fix backend version check for
, , and . -
Bug fixes related to old versions of dialog (e.g., 1.1-20100428) and Python (3.0 and 3.1, untested on 3.0—please report if you care about this ancient version).
(This includes a fix for a crash in examples/demo.py when the dialog backend is too old to have the widget.)
Main changes in version 3.2.1
The main change in version 3.2.1 is an improved tutorial chapter in the pythondialog Manual.
Main changes in version 3.2.0
The main changes in version 3.2.0 are:
-
New manual generated with Sphinx. Check it out!
-
The default values for day, month and year in the dialog, and it would be quite unintuitive to have them default to -1 with the year still defaulting to 0.
widget have been changed from 0 to -1. This is unfortunately BACKWARD-INCOMPATIBLE, but 0 doesn't work well for day and month inThis change should affect very few people, if any, which is why I decided to fix the API now without increasing the major version number.
Main changes in version 3.1.0
The main changes in version 3.1.0 are:
-
Experimental support for automatic widget size
The
Dialog
class constructor accepts a new keyword-only argument:autowidgetsize
. It is a boolean and currently defaults toFalse
in order to preserve backward-compatibility.When set to
True
, pythondialog's widget-producing methods will behave as ifwidth=0
,height=0
, etc. had been passed, except where these parameters are explicitely specified with different values. This has the effect that, except where you explicitely specify a size parameter such aswidth
orheight
, the dialog backend will automatically compute a suitable widget size for you.Notes:
-
In order to differentiate between a default value obtained when
autowidgetsize
is disabled and an explicitely-specifiedwidth
,height
, etc., the size parameters modified by this change now default toNone
. In order to compensate for this information loss, the effective default values whenautowidgetsize
isFalse
are now mentioned in the docstrings of the corresponding widget-producing methods. -
The
autowidgetsize
option is currently marked as experimental. It may default toTrue
in the next major release; please give some feedback on the mailing list if you care. -
You may encounter questionable results if you only set one of the
width
andheight
parameters to 0 for a given widget (seen in dialog 1.2-20140219).
Examples using the
autowidgetsize
option can be found in the examples/with-autowidgetsize directory of the pythondialog distribution. -
-
Improved installation instructions
-
Removal of
_create_temporary_directory()
in favor oftempfile.NamedTemporaryFile()
There was no security problem in
_create_temporary_directory()
as far as I know, however it is usually better to use well-tested library functions whenever possible instead of custom ones. When_create_temporary_directory()
was written, what was available from the tempfile module was not satisfactory, but this is not the case anymore.This change brings a small BACKWARD INCOMPATIBILITY: the
UnableToCreateTemporaryDirectory
exception is not defined anymore.Dialog.scrollbox()
now creates a temporary file without any temporary directory, therefore there is no place anymore for this exception to be used. The equivalent condition intempfile.NamedTemporaryFile()
generates anOSError
exception (more precisely, aFileExistsError
in Python 3.3 or later, which is a subclass ofOSError
). As usual, this exception is wrapped by pythondialog and seen as aPythonDialogOSError
by user code.Conclusion: wherever user code was expecting
UnableToCreateTemporaryDirectory
in previous versions, it should now expect aPythonDialogOSError
, consistently with the tempfile module andOSError
wrapping by pythondialog.This incompability should affect so few users, if any, that I think increasing the major number just for it would have caused more harm than good.
-
The dialog 1.2-20140112 and the demo uses it in a better way.
widget has been improved in -
The files demo.py and simple_example.py have been moved to the examples directory of the source distribution.
Main changes in version 3.0.1
Compared to version 3.0.0, version 3.0.1 has minor improvements and a backport to Python 2. Go to the PyPI entry for the Python 2 backport for more information concerning this backport.
Main changes in version 3.0.0
The major version number has been increased because this version is not completely backward-compatible with version 2. However, the backward-incompatible changes are small and unlikely to affect many people, if any (see below). The main changes in version 3.0.0 are:
-
Full help support for all widgets
You can now use the keyword arguments (“dialog common options”)
help_button
,help_label
,item_help
,help_tags
andhelp_status
with any widget to provide help facilities to the user (as long as the dialog backend supports the corresponding options). Please refer to the pythondialog Manual for details. demo.py has a number of examples showing how to implement help support in user code.The API extends what was already present for help support in the dialog output after the Help button has been pressed, because this is now automatically done by pythondialog in order to return ready to use, structured data. If you only check the Dialog exit code, you are not affected.
widget. Backward-compatibility is only affected for people who used to parse thepythondialog should now offer access to all help facilities provided by the dialog backend.
-
Nicer exit codes for widget-producing methods
The old, low-level exit codes
d.DIALOG_OK
,d.DIALOG_CANCEL
,d.DIALOG_ESC
,d.DIALOG_HELP
,d.DIALOG_ITEM_HELP
andd.DIALOG_EXTRA
are deprecated (where d is aDialog
instance). They still work, but trigger a DeprecationWarning (see README.rst or its HTML rendering for instructions on how to enable deprecation warnings).You should now use
d.OK
,d.CANCEL
,d.ESC
,d.HELP
andd.EXTRA
, or equivalentlyDialog.OK
,Dialog.CANCEL
,Dialog.ESC
,Dialog.HELP
andDialog.EXTRA
(attributes of theDialog
class). These are called the high-level exit codes, or Dialog exit codes, and defined as strings:"ok"
,"cancel"
,"esc"
,"help"
and"extra"
. You should use the==
operator when comparing to these codes.Notes:
-
There is no ITEM_HELP in the high-level exit codes: the DIALOG_HELP and DIALOG_ITEM_HELP low-level codes are both translated into
Dialog.HELP
. Indeed, the program that has to interpret the code already knows whether it useditem_help=True
in the widget call or not. Both cases correspond to the same user action: the Help button being pressed. Therefore, the distinction is not useful to user code. -
As said, the values of the high-level exit codes are strings:
"ok"
,"cancel"
,"esc"
,"help"
and"extra"
. You may use the string literals directly in your code, instead ofd.OK
orDialog.OK
,d.CANCEL
orDialog.CANCEL
, etc. With proper syntax highlighting, this produces good-looking code, but offers no protection against typos, contrary to theDialog
class attributesDialog.OK
and friends. Apart from that, it is mostly a matter of taste. -
Backward-compatibility should only be affected for code that relies on the nature of
d.DIALOG_OK
,d.DIALOG_CANCEL
,d.DIALOG_ESC
,d.DIALOG_HELP
,d.DIALOG_ITEM_HELP
andd.DIALOG_EXTRA
, which were integers in pythondialog 2 and are now strings (the deprecated attributes are mapped to the high-level exit codes, so that the vast majority of old user code still works without modification, despite the changes).
-
-
Better Extra button support
-
A few widgets, when the Extra button was pressed, used to return
None
instead of the expected value corresponding to user input. This is fixed. -
Similarly to help support, pythondialog now automatically parses the dialog output when the Extra button has been pressed, in order to return ready to use, structured data (normally: the same as if OK had been pressed). This is backward-incompatible.
Extra button support should now be as good as in the dialog backend. See the
Dialog
class docstring for details. -
-
-
New
retval_is_code
decorator that sets the attribute of the same name on its argument. This attribute allows to reliably detect if a widget-producing method returns a Dialog exit code or a sequence whose first element is a Dialog exit code. This is used in the demo, and was necessary since the new exit codes from widget-producing methods are strings, and thus sequences.
Main changes in version 2.14.1
The main changes in version 2.14.1 are:
-
decorate
Dialog.form
with thewidget
decorator (forgotten in version 2.14.0); -
better reporting of dialog errors: when dialog exits with status DIALOG_ERROR, write its output as part of the
DialogError
exception that is raised. This should make it much easier to understand the cause of errors. -
in the
demo, handle the case wheresubprocess.DEVNULL
is not defined, since this attribute was added in Python 3.3; -
easier management of the ChangeLog file.
Main changes in version 2.14.0
The main changes in version 2.14.0 are:
-
Add support for the
, and widgets. -
Add support for new dialog common options:
--default-button
and--no-tags
. -
In dialog.py, use a context manager to factor out
OSError
andIOError
handling throughout the module. -
dialog.py has a new
version_info
module-level attribute, similar to what thesys
module provides. This avoids the need to parse__version__
when one wants to extract for instance the major and/or minor version number of pythondialog. -
Backend version caching and comparing
Slight modification to a recent API: when the dialog-like backend does not return DIALOG_OK,
Dialog.backend_version()
raisesUnableToRetrieveBackendVersion
(new exception) instead of returning None. This way, the method either returns a string or raises an exception.dialog.py has a new
DialogBackendVersion
class (andBackendVersion
abstract base class) for parsing the version string of the dialog backend, storing it in a structured format, and providing easy and reliable comparisons between versions using the standard comparison operators (<, <=, ==, !=, >=, >).Dialog.__init__
retrieves the backend version and stores the corresponding (Dialog)BackendVersion instance into a publiccached_backend_version
attribute. This should avoid having to run 'backend --print-version' every time someone needs the version. -
Check for too old versions of the backend
dialog.py has a new exception called
InadequateBackendVersion
that is raised when the user tries to use a , or widget with a dialog version that does not implement the widget in question (of course, similar checks will be added for future widgets).Similarly, for the latest widgets added to dialog, the demo checks the version of the backend if it's dialog and displays an explanation instead of the widget demo when it is too old.
-
Add an
is_widget
attribute toDialog
widget-producing methodsdialog.widget
is a new decorator to mark theDialog
methods that provide a widget. As explained in the docstring, this allows code to perform automatic operations on these specific methods. For instance, one can define a class that behaves similarly toDialog
, except that after every widget-producing call, it spawns a "confirm quit" dialog if the widget returned DIALOG_ESC, and loops in case the user doesn't actually want to quit. -
Improve structure and ESC handling in the demo
-
New
MyApp
class that implements the core of the demo. This class relies on a newMyDialog
class that automatically wraps every widget-producing method ofdialog.Dialog
in order to display the "confirm quit" dialog if the user presses the Escape key or the Cancel button. This class also provides a few dialog-related methods used in the demo. -
This new structure should completely fix handling of the
Escape key, which was not satisfactory in previous versions
since it required a while loop for every widget call that made
the code redundant and harder to read. The new wrapping
mechanism is completely transparent for most of the code in
MyApp
, which thus becomes shorter, more reliable and easier to read. The "magic" is contained within theMyDialog
class.
-
New
-
Add a sample program called simple_example.py that is really intended for newcomers: short, straightforward, with absolutely no magic.
-
In demo.py, move a bunch of widget demos from
MyApp.additional_widgets()
to the mainMyApp.demo()
method to give them more visibility. The remaining widgets inMyApp.additional_widgets()
either have little warts (like which is waiting for a fix in the dialog backend), are cumbersome for the person running the demo (this is the case ofprogressbox_demo_with_filepath
), or are almost identical to widgets already presented in the main part of the demo.
Main changes in version 2.13.1
The main change in version 2.13.1 is:
-
remove the default /usr/local installation prefix in setup.cfg that broke installations with pip in a virtualenv, at least.
Main changes in version 2.13
The main changes in version 2.13 are:
-
a new
set_background_title()
method (replacing the long-obsoletesetBackgroundTitle()
from pythondialog 1.0) that does proper “dash escaping”1; -
documentation improvements for the
Dialog
class.
Main changes in version 2.12
The main changes in version 2.12 are:
-
Python 3 support. You can (and should) now pass “normal” strings to pythondialog calls, which correspond to Unicode strings in Python 2-speak. Python will automatically encode the arguments according to the current locale when calling dialog. pythondialog-based scripts can be written in any encoding (using an encoding declaration if the encoding is not UTF-8), and everything will be automatically recoded according to the user's locale when he runs the script.
Of course, if the script tries to display a character that can't be represented in the user's locale, there is a problem. For instance, the “Ÿ” (LATIN CAPITAL LETTER Y WITH DIAERESIS) and euro sign don't exist in ISO 8859-1, therefore if the terminal is running under a locale based on ISO 8859-1, it can't display any of these characters and there is nothing that pythondialog can do about that. However, if using only characters that can be represented in the user's locale, there is no problem and everything is automatically translated between the encoding of the Python script and the encoding defined by the user's locale. In particular, this last condition is almost always satisfied when the user's locale is based on Unicode, since this character set can represent just about anything that can be found in the myriad of legacy character sets.
-
Proper escaping of user-supplied values in case they start with two dashes (“--”). Such strings could be confused with dialog options in previous versions, since pythondialog didn't do any such escaping before version 2.12.
-
Much easier debugging, with
Dialog.setup_debug()
, its optional use in the demo and the new traceback handling thanks to thetraceback
module (see the pythondialog Manual, history link on the Git repository, or ChangeLog file in a release tarball for details). In case there is a problem with the demo, or if you just want to look under the hood, you can now run it with --debug (and optionally --debug-file) to make it write the full dialog command lines to a file. -
Standard exception behavior: if e is a
dialog.error
instance (or an instance of adialog.error
subclass), thenstr(e)
returns nothing more than the exception message, as with all Python built-in exceptions. No need to writee.complete_message()
anymore. -
Support for many “common options” has been added:
--ascii-lines
,--colors
,--column-separator
,--date-format
,--exit-label
,--extra-button
,--extra-label
,--hfile
,--hline
,--keep-tite
,--keep-window
,--no-collapse
,--no-lines
,--no-mouse
,--no-nl-expand
,--no-ok
,--scrollbar
,--time-format
,--trace
and--visit-items
. The new methodDialog.maxsize()
allows one to find the terminal size and know how many lines and columns are available for a dialog box. -
The pythondialog version is now accessible as
dialog.__version__
(attribute of thedialog
module), as per Python standards; additionally, the version of the dialog backend in use can be obtained withDialog.backend_version()
(method ofDialog
instances). -
Transition from
PythonDialogIOError
toPythonDialogOSError
. As you may be aware of, the exception hierarchy has been reworked in Python 3.3, and from this version onwards,IOError
is an alias ofOSError
. In this context, it would be nice to get rid ofPythonDialogIOError
in favor ofPythonDialogOSError
. pythondialog 2.12 prepares this transition in the following way.PythonDialogIOError
is now a subclass ofPythonDialogOSError
so that users can safely replaceexcept PythonDialogIOError
clauses withexcept PythonDialogOSError
even if running under Python < 3.3. pythondialog will raisePythonDialogOSError
instead ofPythonDialogIOError
when Python stops distinguishing betweenIOError
andOSError
, i.e. when running under Python 3.3 or later.
Footnotes
1. This could be useful if you (somewhat strangely) chose a backtitle that starts with a double dash (“--”). Without dash escaping, it might be mistaken for a dialog option.