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.
In short, the latest versions (2.12 and later) only support Python 3, except for version 3.0.1, which has been backported to Python 2.
Python 2 users
Since version 2.12, the reference implementation of pythondialog does not support Python 2 anymore. However, a backport of pythondialog 3.0.1 to Python 2 is available here. Users who really want to stick to Python 2 should use version 3.0.1 or 2.11:
- version 2.11 is 100 %-compatible with previous releases, but is old and only supports Python 2;
- version 3.0.1 is recent, available for both Python 2 and Python 3, but has a few small incompatibilities with versions 2.x that are summarized below. Besides, before using pythondialog 3 under Python 2, be sure to read the backport-specific notes in the README.rst file (HTML rendering for the latest version here).
The naming of each tarball clearly indicates which major version of Python it has been prepared for (well, this is the case for the SourceForge download page and the PyPI entry for the Python 2 backport, but unfortunately not for the main PyPI entry, where the name of uploaded tarballs is constrained by the entry name).
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_statuswith any widget to provide help facilities to the user (as long as the dialog backend supports the corresponding options). Please refer to the Dialog class docstring in the documentation 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 'menu' widget. Backward-compatibility is only affected for people who used to parse 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.
pythondialog 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_EXTRAare deprecated (where d is a Dialog 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.EXTRA, or equivalently
Dialog.EXTRA(attributes of the Dialog 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.
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 used
item_help=Truein 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 of
Dialog.CANCEL, etc. With proper syntax highlighting, this produces good-looking code, but offers no protection against typos, contrary to the Dialog class attributes
Dialog.OKand 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_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
Noneinstead 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.
'buildlist' widget support
retval_is_codedecorator 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:
Dialog.formwith the 'widget' 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 programbox demo, handle the case where
subprocess.DEVNULLis 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 'programbox', 'rangebox' and 'treeview' widgets.
Add support for new dialog common options:
In dialog.py, use a context manager to factor out OSError and IOError handling throughout the module.
dialog.py has a new
version_infomodule-level attribute, similar to what the
sysmodule 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,
UnableToRetrieveBackendVersion(new exception) instead of returning None. This way, the method either returns a string or raises an exception.
dialog.py has a new
BackendVersionabstract 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 public
cached_backend_versionattribute. 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
InadequateBackendVersionthat is raised when the user tries to use a programbox, rangebox or treeview 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 to Dialog widget-producing methods
dialog.widgetis a new decorator to mark the Dialog 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 to Dialog, 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 new MyDialog class that automatically wraps every widget-producing method of dialog.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 the MyDialog class.
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 main
MyApp.demo()method to give them more visibility. The remaining widgets in
MyApp.additional_widgets()either have little warts (like programbox which is waiting for a fix in the dialog backend), are cumbersome for the person running the demo (this is the case of
progressbox_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:
set_background_title()method (replacing the long-obsolete
setBackgroundTitle()from pythondialog 1.0) that does proper “dash escaping”1;
documentation improvements for the
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 the
tracebackmodule (see the documentation, 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.errorinstance (or an instance of a
str(e)returns nothing more than the exception message, as with all Python built-in exceptions. No need to write
Support for many “common options” has been added:
--visit-items. The new method
Dialog.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 the
dialogmodule), as per Python standards; additionally, the version of the dialog backend in use can be obtained with
PythonDialogOSError. As you may be aware of, the exception hierarchy has been reworked in Python 3.3, and from this version onwards,
IOErroris an alias of
OSError. In this context, it would be nice to get rid of
PythonDialogIOErrorin favor of
PythonDialogOSError. pythondialog 2.12 prepares this transition in the following way.
PythonDialogIOErroris now a subclass of
PythonDialogOSErrorso that users can safely replace
except PythonDialogIOErrorclauses with
except PythonDialogOSErroreven if running under Python < 3.3. pythondialog will raise
PythonDialogIOErrorwhen Python stops distinguishing between
OSError, i.e. when running under Python 3.3 or later.
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.