Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add back dialogs #2

Merged
merged 87 commits into from
Aug 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
748f044
Add back dialogs
altendky Jun 18, 2020
5a49561
Merge branch 'master' into dialogs
altendky Jun 22, 2020
0790005
catch up with PySide2 support
altendky Jun 22, 2020
a0823de
Merge branch 'master' into dialogs
altendky Jun 22, 2020
d5c7980
Add some dialogs
altendky Jun 23, 2020
4160bae
allow FileDialog to not find buttons
altendky Jun 23, 2020
1e10b89
select the directory before the file, maybe
altendky Jun 23, 2020
29c2701
set the default path ahead for file dialog test
altendky Jun 23, 2020
70e8686
Merge branch 'master' into dialogs
altendky Jun 23, 2020
7c4ab04
actually do the last thing
altendky Jun 23, 2020
178ffa6
trio.Path() for test_file_save()
altendky Jun 23, 2020
fb5e377
maybe avoid a race and...
altendky Jun 23, 2020
9b4f7a1
Correct text input dialog shown signal parameter type
altendky Jun 23, 2020
1076979
Rework IntegerDialog to maybe avoid a race
altendky Jun 23, 2020
b28f094
Separate default directory and file
altendky Jun 23, 2020
4c7c1eb
non-native file dialog on macOS
altendky Jun 23, 2020
b3e3b30
hmm
altendky Jun 23, 2020
fce79ac
again
altendky Jun 23, 2020
bac2d5e
it's DontUseNativeDialog
altendky Jun 23, 2020
8aad207
rework test_wait_signal_waits
altendky Jun 24, 2020
f1d8b3a
Undo unrelated test changes
altendky Jul 14, 2020
b99b500
Merge branch 'master' into dialogs
altendky Jul 14, 2020
e96b61d
catchup
altendky Jul 15, 2020
8b7642f
diagnostic always uses non-native
altendky Jul 21, 2020
630ad35
Merge branch 'master' into dialogs
altendky Jul 24, 2020
ed14842
add newsfragments/2.feature.rst
altendky Jul 24, 2020
578a75f
Only non-native for macOS
altendky Jul 24, 2020
6cd7615
allow cancellation in the test
altendky Jul 24, 2020
234705a
give it more time?
altendky Jul 25, 2020
b233829
Merge branch 'master' into dialogs
altendky Jul 31, 2020
a06d76d
Raise timeout on failing tests
altendky Jul 31, 2020
8504f11
hmm
altendky Aug 1, 2020
ce60d1f
do we like classmethods?
altendky Aug 1, 2020
1f4966f
this will move elsewhere
altendky Aug 1, 2020
0670e89
move UserCancelledError back where it was
altendky Aug 1, 2020
983b564
Merge branch 'master' into dialogs
altendky Aug 3, 2020
4426bb4
Merge branch 'master' into dialogs
altendky Aug 3, 2020
9006352
30 second timeout. ?!???!??!??!?
altendky Aug 4, 2020
5008764
30 second timeout. ?!???!??!??!?
altendky Aug 4, 2020
8f30d50
double up
altendky Aug 4, 2020
0225898
less bleh
altendky Aug 4, 2020
b599977
.setup()
altendky Aug 4, 2020
8641bcd
general messagebox
altendky Aug 4, 2020
28bad29
maybe this time i'm done
altendky Aug 4, 2020
9d1cf91
Merge branch 'master' into dialogs
altendky Aug 4, 2020
9e33354
remove the event already set check... again
altendky Aug 4, 2020
bc0b25b
text input dialog test coverage
altendky Aug 4, 2020
bf614d7
tidy
altendky Aug 4, 2020
a9187cd
some more test coverage
altendky Aug 4, 2020
b160a61
black
altendky Aug 4, 2020
256ac83
flake8
altendky Aug 4, 2020
f9f41f4
report cancellation errors
altendky Aug 4, 2020
3f598d3
longer timeout. again. really?
altendky Aug 5, 2020
b397e95
findChildren for setting non-existent file name in windows
altendky Aug 5, 2020
72863a1
black
altendky Aug 5, 2020
e86ee99
monkeypatch codecs to figure out the full bytes
altendky Aug 5, 2020
0a863db
PYTHONIOENCODING
altendky Aug 5, 2020
11e1e02
Add todo and link for PYTHONIOENCODING
altendky Aug 5, 2020
33e19ef
100
altendky Aug 5, 2020
7710ba0
HEAD too
altendky Aug 5, 2020
cd8e33c
no HEAD?
altendky Aug 5, 2020
d713284
deepen
altendky Aug 5, 2020
a127b16
Merge branch 'master' into dialogs
altendky Aug 5, 2020
cb05565
remove manage_progress_dialog
altendky Aug 5, 2020
3fb467f
Add test for non-timeout trio.TooSlowError passing out
altendky Aug 5, 2020
72077c1
Merge branch 'master' into dialogs
altendky Aug 5, 2020
a5c99e4
Merge branch 'master' into dialogs
altendky Aug 6, 2020
22358fb
please let me not change this timeout right now
altendky Aug 6, 2020
6d7ca4c
make qtrio.dialogs public
altendky Aug 6, 2020
aafabf5
Merge branch 'master' into dialogs
altendky Aug 6, 2020
30b9944
remove IntegerDialog retry feature, use tenacity or such
altendky Aug 6, 2020
8e9781d
remove attempts
altendky Aug 6, 2020
de576a9
Merge branch 'master' into dialogs
altendky Aug 8, 2020
61944c2
stuff
altendky Aug 9, 2020
b093f76
what it is right now
altendky Aug 10, 2020
b7b9514
step
altendky Aug 12, 2020
ab34e93
Merge branch 'master' into dialogs
altendky Aug 13, 2020
9423079
Merge branch 'master' into dialogs
altendky Aug 21, 2020
3c2fe4b
more
altendky Aug 21, 2020
1c8580c
typing-extensions for Protocol
altendky Aug 21, 2020
cac9555
black
altendky Aug 21, 2020
a382a52
some hints
altendky Aug 21, 2020
89eb5d2
some more # pragma: no cover
altendky Aug 21, 2020
d71d781
more time for macos
altendky Aug 21, 2020
3919989
always more. more. more!
altendky Aug 22, 2020
4ea256f
getting close
altendky Aug 22, 2020
da40b97
trickle
altendky Aug 22, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .readthedocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ build:
image: latest

python:
version: 3
version: 3.8
install:
- method: pip
path: .
Expand Down
5 changes: 5 additions & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,13 @@
("py:class", "qtrio._core.EmissionsNursery"),
("py:class", "qtrio._core.Outcomes"),
("py:class", "qtrio._core.Reenter"),
("py:class", "qtrio._qt.Signal"),
# https://github.com/Czaki/sphinx-qt-documentation/issues/10
("py:class", "<class 'PySide2.QtCore.QEvent.Type'>"),
("py:class", "<class 'PySide2.QtWidgets.QFileDialog.FileMode'>"),
("py:class", "<class 'PySide2.QtWidgets.QFileDialog.AcceptMode'>"),
("py:class", "<class 'PySide2.QtWidgets.QFileDialog.Option'>"),
("py:class", "<class 'PySide2.QtWidgets.QMessageBox.Icon'>"),
# https://github.com/sphinx-doc/sphinx/issues/8136
("py:class", "typing.AbstractAsyncContextManager"),
]
Expand Down
5 changes: 5 additions & 0 deletions docs/source/core.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ their errors on the floor they will be run inside a nursery.
.. autofunction:: qtrio.open_emissions_nursery
.. autoclass:: qtrio.EmissionsNursery

Helpers
-------

.. autoclass:: qtrio.Signal

Reentry Events
--------------

Expand Down
38 changes: 38 additions & 0 deletions docs/source/dialogs.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
Dialogs
=======

Usage Pattern
-------------

Creation Functions
------------------

.. autofunction:: qtrio.dialogs.create_integer_dialog
.. autofunction:: qtrio.dialogs.create_text_input_dialog
.. autofunction:: qtrio.dialogs.create_file_save_dialog
.. autofunction:: qtrio.dialogs.create_message_box


Classes
-------

.. autoclass:: qtrio.dialogs.IntegerDialog
:members:

.. autoclass:: qtrio.dialogs.TextInputDialog
:members:

.. autoclass:: qtrio.dialogs.FileDialog
:members:

.. autoclass:: qtrio.dialogs.MessageBox
:members:


Protocol
--------

.. autoclass:: qtrio.dialogs.DialogProtocol
:members:

.. autofunction:: qtrio.dialogs.check_dialog_protocol
3 changes: 3 additions & 0 deletions docs/source/exceptions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ Exceptions
.. autoclass:: qtrio.RequestedEventTypeUnavailableError
.. autoclass:: qtrio.EventTypeAlreadyRegisteredError
.. autoclass:: qtrio.ReturnCodeError
.. autoclass:: qtrio.InternalError
.. autoclass:: qtrio.UserCancelledError
.. autoclass:: qtrio.InvalidInputError
1 change: 1 addition & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
tutorial.rst
core.rst
testing.rst
dialogs.rst
exceptions.rst
examples/examples.rst
development/index.rst
Expand Down
1 change: 1 addition & 0 deletions newsfragments/2.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Introduce QTrio specific wrappers for some builtin dialogs.
4 changes: 4 additions & 0 deletions qtrio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
EventTypeAlreadyRegisteredError,
ReturnCodeError,
RunnerTimedOutError,
UserCancelledError,
InvalidInputError,
InternalError,
)

from ._core import (
Expand All @@ -28,4 +31,5 @@
Reenter,
)

from ._qt import Signal
from ._pytest import host
14 changes: 14 additions & 0 deletions qtrio/_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,13 @@ def __eq__(self, other: object) -> bool:
return self.args == other.args


class InternalError(QTrioException):
"""Raised when an internal state is inconsistent."""

# https://github.com/sphinx-doc/sphinx/issues/7493
__module__ = "qtrio"


class UserCancelledError(QTrioException):
"""Raised when a user requested cancellation of an operation."""

Expand All @@ -97,3 +104,10 @@ class RunnerTimedOutError(QTrioException):

# https://github.com/sphinx-doc/sphinx/issues/7493
__module__ = "qtrio"


class InvalidInputError(QTrioException):
"""Raised when invalid input is provided such as via a dialog."""

# https://github.com/sphinx-doc/sphinx/issues/7493
__module__ = "qtrio"
22 changes: 13 additions & 9 deletions qtrio/_qt.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@


class Signal:
"""This is a (nearly) drop-in replacement for QtCore.Signal. The useful difference
is that it does not require inheriting from :class:`QtCore.QObject`. The not-quite
part is that it will be a bit more complicated to change thread affinity of the
relevant :class:`QtCore.QObject`. If you need this, maybe just inherit.
"""This is a (nearly) drop-in replacement for :class:`QtCore.Signal`. The useful
difference is that it does not require inheriting from :class:`QtCore.QObject`. The
not-quite part is that it will be a bit more complicated to change thread affinity
of the relevant :class:`QtCore.QObject`. If you need this, maybe just inherit.

This signal gets around the normally required inheritance by creating
:class:`QtCore.QObject` instances behind the scenes to host the real signals. Just
Expand All @@ -22,7 +22,7 @@ class Signal:
object.
"""

attribute_name: str = ""
_attribute_name: typing.ClassVar[str] = ""

def __init__(self, *args: object, **kwargs: object) -> None:
class _SignalQObject(QtCore.QObject):
Expand All @@ -39,19 +39,23 @@ def __get__(self, instance: object, owner: object) -> qtrio._util.SignalInstance
return o.signal

def object(self, instance: object) -> QtCore.QObject:
"""Get the :class:`QtCore.QObject` that hosts the real signal.
"""Get the :class:`QtCore.QObject` that hosts the real signal. This can be
called such as ``type(instance).signal_name.object(instance)``. Yes this is
non-obvious but you have to do something special to get around the
:ref:`descriptor protocol <python:descriptors>` so you can get at this method
instead of just having the underlying :class:`QtCore.SignalInstance`.

Arguments:
instance: The object on which this descriptor instance is hosted.

Returns:
The signal-hosting :class:`QtCore.QObject`.
"""
d = getattr(instance, self.attribute_name, None)
d = getattr(instance, self._attribute_name, None)

if d is None:
d = {}
setattr(instance, self.attribute_name, d)
setattr(instance, self._attribute_name, d)

o = d.get(self.object_cls)
if o is None:
Expand All @@ -61,7 +65,7 @@ def object(self, instance: object) -> QtCore.QObject:
return o


Signal.attribute_name = qtrio._python.identifier_path(Signal)
Signal._attribute_name = qtrio._python.identifier_path(Signal)


@contextlib.contextmanager
Expand Down
Loading