I believe lightning requests created before https://github.com/spesmilo/electrum/pull/7730
can have an amount of None - ones created after have amount 0 instead.
We could do a wallet db upgrade potentially.
Regardless, the type hint is `get_amount_sat(self) -> Union[int, str, None]`,
so None should be handled. (well, arguably "!" should be handled too...)
```
E | gui.qt.exception_window.Exception_Hook | exception caught by crash reporter
Traceback (most recent call last):
File "...\electrum\electrum\gui\qt\request_list.py", line 101, in item_changed
self.parent.show_receive_request(req)
File "...\electrum\electrum\gui\qt\main_window.py", line 1279, in show_receive_request
URI = req.get_bip21_URI(lightning=bip21_lightning)
File "...\electrum\electrum\invoices.py", line 164, in get_bip21_URI
amount = int(self.get_amount_sat())
TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType'
```
```
E | gui.qt.exception_window.Exception_Hook | exception caught by crash reporter
Traceback (most recent call last):
File "...\electrum\electrum\gui\qt\request_list.py", line 101, in item_changed
self.parent.show_receive_request(req)
File "...\electrum\electrum\gui\qt\main_window.py", line 1281, in show_receive_request
can_receive_lightning = self.wallet.lnworker and req.get_amount_sat() <= self.wallet.lnworker.num_sats_can_receive()
TypeError: '<=' not supported between instances of 'NoneType' and 'decimal.Decimal'
```
/home/user/wspace/electrum/electrum/gui/qt/locktimeedit.py:145: DeprecationWarning: an integer is required (got type Alignment). Implicit conversion to integers using __int__ is deprecated, and may be removed in a future version of Python.
painter.drawText(textRect, Qt.AlignRight | Qt.AlignVCenter, "height")
InvoiceList.update() calls hide_if_empty(), which calls setVisible().
setVisible(True) should not be called before the widget is properly parented and put into a layout,
as that results in a blank window flashing up (appearing and disappearing) briefly.
distutils (a module in the python standard library that we use) got deprecated in python 3.10,
and is planned to be removed from the stdlib in python 3.12.
see 9d38120e33/Lib/distutils/__init__.py (L16)
We only use it in the Qt update_checker (for signed version notifications), to compare version numbers.
That is, we only use a very small part of it (only `distutils.version.StrictVersion`).
```
.../electrum/electrum/gui/qt/update_checker.py:7: DeprecationWarning: The distutils package is deprecated and slated for removal in Python 3.12. Use setuptools or check PEP 632 for potential alternatives
from distutils.version import StrictVersion
```
Migration advice in PEP-632 suggests ( https://peps.python.org/pep-0632/#migration-advice ):
> `distutils.version` — use the `packaging` package
Note that `packaging` is a 3rd party package, i.e. it would be a new dependency.
Also, it does not provide an identical replacement for `distutils.version.StrictVersion`.
Care needs to be taken when changing the semantics of version numbers...
E.g. `packaging.parse` and `packaging.Version` are less strict than what we currently use.
We have to be careful that old code recognises new electrum version numbers as both valid
and numerically greater than their version.
I think the easiest approach is for us to vendor this small part of distutils.
Re directory structure, this is based on `pip`:
bab5bfce50/src/pip/_vendor
(although the approach here is much more naive ofc)
asyncio.get_event_loop() became deprecated in python3.10. (see https://github.com/python/cpython/issues/83710)
```
.../electrum/electrum/daemon.py:470: DeprecationWarning: There is no current event loop
self.asyncio_loop = asyncio.get_event_loop()
.../electrum/electrum/network.py:276: DeprecationWarning: There is no current event loop
self.asyncio_loop = asyncio.get_event_loop()
```
Also, according to that thread, "set_event_loop() [... is] not deprecated by oversight".
So, we stop using get_event_loop() and set_event_loop() in our own code.
Note that libraries we use (such as the stdlib for python <3.10), might call get_event_loop,
which then relies on us having called set_event_loop e.g. for the GUI thread. To work around
this, a custom event loop policy providing a get_event_loop implementation is used.
Previously, we have been using a single asyncio event loop, created with
util.create_and_start_event_loop, and code in many places got a reference to this loop
using asyncio.get_event_loop().
Now, we still use a single asyncio event loop, but it is now stored as a global in
util._asyncio_event_loop (access with util.get_asyncio_loop()).
I believe these changes also fix https://github.com/spesmilo/electrum/issues/5376