Skip to content

Commit

Permalink
Merge branch 'main' into fix-issue-1205
Browse files Browse the repository at this point in the history
  • Loading branch information
capn-freako authored Nov 24, 2023
2 parents 732047f + 46f7009 commit ff779d8
Show file tree
Hide file tree
Showing 156 changed files with 2,831 additions and 739 deletions.
1 change: 1 addition & 0 deletions .github/actions/install-qt-support/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ runs:
sudo apt-get install libxcb-render-util0
sudo apt-get install libxcb-xinerama0
sudo apt-get install libxcb-shape0
sudo apt-get install libxcb-cursor0
sudo apt-get install pulseaudio
sudo apt-get install libpulse-mainloop-glib0
# Needed to work around https://bugreports.qt.io/browse/PYSIDE-1547
Expand Down
56 changes: 56 additions & 0 deletions .github/workflows/test-docs-with-edm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# This workflow targets stable released dependencies from EDM.
# Note that some packages may not actually be installed from EDM but from
# PyPI, see etstool.py implementations.

name: Build docs with EDM

on: [pull_request, workflow_dispatch]

env:
INSTALL_EDM_VERSION: 3.5.0
QT_MAC_WANTS_LAYER: 1

jobs:

# Build docs using EDM packages
docs-with-edm:
strategy:
matrix:
os: [ubuntu-latest]
toolkit: ['pyside6']
fail-fast: false
timeout-minutes: 20 # should be plenty, it's usually < 5
runs-on: ${{ matrix.os }}
env:
# Set root directory, mainly for Windows, so that the EDM Python
# environment lives in the same drive as the cloned source. Otherwise
# 'pip install' raises an error while trying to compute
# relative path between the site-packages and the source directory.
EDM_ROOT_DIRECTORY: ${{ github.workspace }}/.edm
steps:
- uses: actions/checkout@v3
- name: Install Qt dependencies
uses: ./.github/actions/install-qt-support
if: matrix.toolkit != 'wx'
- name: Cache EDM packages
uses: actions/cache@v3
with:
path: ~/.cache
key: ${{ runner.os }}-${{ matrix.toolkit }}-${{ hashFiles('etstool.py') }}
- name: Setup EDM
uses: enthought/setup-edm-action@v2
with:
edm-version: ${{ env.INSTALL_EDM_VERSION }}
- name: Install click to the default EDM environment
run: edm install -y wheel click coverage
- name: Install test environment
run: edm run -- python etstool.py install --toolkit=${{ matrix.toolkit }}
- name: Build docs
run: xvfb-run -a edm run -- python etstool.py docs --toolkit=${{ matrix.toolkit }}
- name: Archive HTML docs
uses: actions/upload-artifact@v3
with:
name: html-doc-bundle
path: docs/build/html
# don't need these kept for long
retention-days: 7
2 changes: 2 additions & 0 deletions .github/workflows/test-with-edm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ jobs:
test-with-edm:
strategy:
matrix:
# Note: MacOS support is contingent on not hitting any issues with
# unsupported CPU features such as AVX2 and so may be unstable.
os: [ubuntu-latest, macos-latest, windows-latest]
toolkit: ['pyside6']
fail-fast: false
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
build/
dist/
docs/build/
docs/source/api

# Auto-generated by setup.py
pyface/_version.py
148 changes: 148 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,154 @@
Pyface Changelog
================

Release 8.0.0
=============

Highlights of this release
--------------------------

This is a major release which removes a number of things which have been
deprecated for a number of years. The most significant change in this release
is that the Qt toolkit backend has been moved from the ``pyface.ui.qt4``
package to the ``pyface.ui.qt`` package. The "qt4" namespace had been an
ongoing source of confusion as Qt5 and Qt6 became the most popular versions of
Qt in use. Because this change has the potential to cause significant backwards
compatibility issues, this release includes import hooks to continue to support
imports from ``pyface.ui.qt4...`` which can be enabled by:

- using "qt4" for the `ETS_TOOLKIT` or `ETSConfig.toolkit` values.
- setting the `ETS_QT4_IMPORT` environment variable to a non-empty value
- explicitly adding the import hooks to `sys.meta_path`

In particular the environment variables allow users of ETS-based applications
such as Mayavi to continue to use those applications with newer versions of
Pyface until there is time to update their code to the new import locations.

Additionally this release uses the module-level ``__getattr__`` system
introduced in Python 3.7 to delay imports from the ``api`` modules which have
side-effects, particularly toolkit selection. This means that you can, for
example, import ``pyface.api`` and toolkit selection will be deferred until
you actually request a class or object which is toolkit-dependent. Part of
this included adding formal interfaces for ``ActionManager`` and its subclasses

In addition this release:

- adds support for Python 3.11 and drops support for Python 3.6
- adds support for PySide 6.4+ and the new enum system
- removes code supporting PyQt4, and supports more modern imports from
`pyface.qt`, such as `pyface.qt.QtWidgets`.
- removes many things flagged as deprecated in Pyface 7
- consistently add interface classes to ``api`` modules.
- adds new Field subclasses, including an ImageField and LabelField
- moves to a pyproject.toml-based packaging solution, removing setup.py

Detailed changes
----------------

Thanks to:

* Mark Dickinson
* Dominik Gresch
* JaRoSchm
* Rahul Poruri
* Corran Webster

Features

* Refactor IField and add IImageField and ILabelField Field classes (#1234)
* Move ``pyface.ui.qt4`` to ``pyface.ui.qt`` (#1223, #1228)
* Delayed imports with side-effects in ``api`` modules; new interfaces for
``ActionManager`` and its subclasses (#1229)

Enhancements

* Better handling of sizes for multiple (or no) screens (#1237)
* More arguments for the ``confirm`` function (#1221)
* Expose interfaces in ``api`` modules and other improvemnts to ``api`` modules
(#1220, #1222, #1229)
* remove deprecated modules and code (#1209, #1215)
* PySide 6.5 support (#1238)
* Python 3.11 and PySide 6.4 support (#1210)

Fixes

* Always use a no-delay timer for ``GUI`` ``invoke_later`` and
``set_trait_later`` on Qt (#1226)
* Work arounds for some end-of-process segfaults on PySide < 6.4.3 (#1214)
* Use ``exec`` instead of ``exec_`` where possible (#1208)
* Emit a warning rather than asserting in SplitTabWidget (#1192)
* Remove required parent argument in Wx StatusBarManager (#1192)
* Use integer division in DockSplitter.draw (#1190)

Documentation

* general updates and enhancements (#1238)
* update copyright dates (#1191)

CI

* remove ``setup.py`` and use ``pyproject.toml`` (#1203, #1214)

Release 7.4.4
=============

Highlights of this release
--------------------------

This is a quick bugfix release that resolves some issues with the 7.4.3 release
on CI for downstream projects. The issues were on testing code, and so
shouldn't impact application code or behaviour.

Detailed changes
----------------

Thanks to:

* Corran Webster

Fixes

* Don't raise ConditionTimeoutError if test doesn't time out (#1182)

CI

* get CI working again with ubuntu-current on GitHub (#1186)

Release 7.4.3
=============

Highlights of this release
--------------------------

This is a bugfix release that collects a number of additional issues discovered
and fixed since the 7.4.2 release. Among the fixes, this pins PySide6 to less than
6.4.0, as 6.4 has breaking changes in it.

Detailed changes
----------------

Thanks to:

* Alex Chabot-Leclerc
* Mark Dickinson
* Eric Larson
* Steven Kern
* Corran Webster

Fixes

* Fix code editor gutter widget on recent Python versions (#1176)
* fix issues with FileDialog and DirectoryDialog close method on Linux (#1175)
* update setup.py metadata (#1173)
* restrict to PySide versions before 6.4.0 (#1169)
* don't do unneccessary evaluations of conditions in EventLoopHelper (#1168)
* fix a deleted object error in PyQt5 (#1161)
* better reporting of toolkit errors (#1157)

Documentation

* fix some Python 2 style print statements in documentation (#1157)

Release 7.4.2
=============

Expand Down
92 changes: 63 additions & 29 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,44 +3,92 @@ Pyface: Traits-capable Windowing Framework
==========================================

The Pyface project contains a toolkit-independent GUI abstraction layer,
which is used to support the "visualization" features of the Traits package.
Thus, you can write code in terms of the Traits API (views, items, editors,
etc.), and let Pyface and your selected toolkit and back-end take care of
the details of displaying them.
which is used to support the "visualization" features of the Enthought Tool
Suite libraries. Pyface contains Traits-aware wrappers of standard GUI
elements such as Windows, Dialogs and Fields, together with the "Tasks"
application framework which provides a rich GUI experience with dock panes,
tabbed editors, and so forth. This permits you to write cross-platform
interactive GUI code without needing to use the underlying GUI backend.

The following GUI backends are supported:

- PySide2 (stable) and PySide6 (experimental)
- PyQt5 (stable) and PyQt6 (in development)
- wxPython 4 (experimental)

Example
-------

The following code creates a window with a simple Python shell:

.. code-block:: python
from pyface.api import ApplicationWindow, GUI, IPythonShell
class MainWindow(ApplicationWindow):
""" The main application window. """
#: The PythonShell that forms the contents of the window
shell = Instance(IPythonShell, allow_none=False)
def _create_contents(self, parent):
""" Create the editor. """
self.shell.create(parent)
return self.shell.control
def destroy(self):
self.shell.destroy()
super().destroy()
def _shell_default(self):
from pyface.api import PythonShell
return PythonShell()
# Application entry point.
if __name__ == "__main__":
# Create the GUI.
gui = GUI()
# Create and open the main window.
window = MainWindow(title="Python Shell", size=(640, 480))
window.open()
# Start the GUI event loop!
gui.start_event_loop()
.. image:: https://raw.github.com/enthought/pyface/main/shell_window.png
:alt: A Pyface GUI window containing a Python shell.

Installation
------------

GUI backends are marked as optional dependencies of Pyface. Some features
or infrastructures may also require additional dependencies.
Pyface is a pure Python package. In most cases Pyface will be installable
using a simple ``pip install`` command.

To install with PySide2 dependencies::
To install with a backend, choose one of the following, as appropriate:

$ pip install pyface[pyside2]
.. code-block:: console
To install with PySide6 dependencies (experimental)::
$ pip install pyface[pyside2]
$ pip install pyface[pyside6]
To install with PyQt5 dependencies::

$ pip install pyface[pyqt5]
To install with wxPython4 dependencies (experimental)::

$ pip install pyface[wx]
``pillow`` is an optional dependency for the PILImage class::
Some optional functionality uses ``pillow`` and ``numpy`` and these can be
installed using optional dependencies:

.. code-block:: console
$ pip install pyface[pillow]
To install with additional test dependencies::
$ pip install pyface[numpy]
For running tests a few more packages are required:

.. code-block:: console
$ pip install pyface[test]
Expand All @@ -51,20 +99,6 @@ Documentation

* `API Documentation <http://docs.enthought.com/pyface/api/pyface.html>`_.

Prerequisites
-------------

Pyface depends on:

* `Traits <https://github.com/enthought/traits>`_

* a GUI toolkit as described above

* Pygments for syntax highlighting in the Qt code editor widget.

* some widgets may have additional optional dependencies such as NumPy or
Pillow.

.. end_of_long_description
Developing Pyface
Expand Down
12 changes: 5 additions & 7 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
# All configuration values have a default value; values that are commented out
# serve to show the default value.

import os
import runpy
import sys
try:
from importlib.metadata import version as metadata_version
except:
from importlib_metadata import version as metadata_version

# General configuration
# ---------------------
Expand Down Expand Up @@ -45,10 +46,7 @@

# The default replacements for |version| and |release|, also used in various
# other places throughout the built documents.
version_py = os.path.join('..', '..', 'pyface', '_version.py')
version_content = runpy.run_path(version_py)
version = ".".join(version_content["version"].split(".", 2)[:2])
release = version
version = release = metadata_version("pyface")

# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
Expand Down
Loading

0 comments on commit ff779d8

Please sign in to comment.