Repository: qtile/qtile

Issue:
CryptoTicker migration is incomplete
I previously had:

```
widget.CryptoTicker(format="BTC: {avg}", **widget_defaults)
```

but it seems avg is not an allowed key any more per:

```
2021-09-01 14:42:17,968 ERROR libqtile generic_poll_text.py:poll():L90 got exception polling widget
Traceback (most recent call last):
  File "/home/tycho/.local/lib/python3.9/site-packages/libqtile/widget/generic_poll_text.py", line 88, in poll
    text = self.parse(body)
  File "/home/tycho/.local/lib/python3.9/site-packages/libqtile/widget/crypto_ticker.py", line 90, in parse
    return self.format.format(**variables)
```

/cc @Graeme22 
CryptoTicker migration is incomplete
I previously had:

```
widget.CryptoTicker(format="BTC: {avg}", **widget_defaults)
```

but it seems avg is not an allowed key any more per:

```
2021-09-01 14:42:17,968 ERROR libqtile generic_poll_text.py:poll():L90 got exception polling widget
Traceback (most recent call last):
  File "/home/tycho/.local/lib/python3.9/site-packages/libqtile/widget/generic_poll_text.py", line 88, in poll
    text = self.parse(body)
  File "/home/tycho/.local/lib/python3.9/site-packages/libqtile/widget/crypto_ticker.py", line 90, in parse
    return self.format.format(**variables)
```

/cc @Graeme22 


Discussion:
Is migration supposed to cover this kind of thing? I wasn't aware.
I'd like us to at least try, it doesn't make much sense to fix some parts of peoples' configs but not others.

On Wed, Sep 1, 2021, at 4:31 PM, Graeme Holliday wrote:
> 
> 
> Is migration supposed to cover this kind of thing? I wasn't aware.
> 
> 
> —
> You are receiving this because you authored the thread.
> Reply to this email directly, view it on GitHub <https://github.com/qtile/qtile/issues/2736#issuecomment-910840636>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AAF7VV4BRQEJC4EF3QLFKMLT72STTANCNFSM5DHMG3AQ>.
> 
So the new default format string is: `'{crypto}: {symbol}{amount:.2f}'`

We *could* just replace the `{avg}` with `{amount}`, however this sort of conceals the new functionality from the user. Is it better to prevent breakage here, or to allow it so that the user can see that they should use a new format string, but one that gives them a higher level of control than before?
I'd say prevent breakage is all that's required.
Is migration supposed to cover this kind of thing? I wasn't aware.
I'd like us to at least try, it doesn't make much sense to fix some parts of peoples' configs but not others.

On Wed, Sep 1, 2021, at 4:31 PM, Graeme Holliday wrote:
> 
> 
> Is migration supposed to cover this kind of thing? I wasn't aware.
> 
> 
> —
> You are receiving this because you authored the thread.
> Reply to this email directly, view it on GitHub <https://github.com/qtile/qtile/issues/2736#issuecomment-910840636>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AAF7VV4BRQEJC4EF3QLFKMLT72STTANCNFSM5DHMG3AQ>.
> 
So the new default format string is: `'{crypto}: {symbol}{amount:.2f}'`

We *could* just replace the `{avg}` with `{amount}`, however this sort of conceals the new functionality from the user. Is it better to prevent breakage here, or to allow it so that the user can see that they should use a new format string, but one that gives them a higher level of control than before?
I'd say prevent breakage is all that's required.

Resolving patch:
diff --git a/libqtile/scripts/migrate.py b/libqtile/scripts/migrate.py
--- a/libqtile/scripts/migrate.py
+++ b/libqtile/scripts/migrate.py
@@ -69,10 +69,32 @@ def pacman_to_checkupdates(query):
     )
 
 
+def reset_format(node, capture, filename):
+    args = capture.get("class_arguments")
+    if args:
+        if args[0].type == 260:  # argument list
+            n_children = len(args[0].children)
+            for i in range(n_children):
+                # we only want to remove the format argument
+                if 'format' in str(args[0].children[i]):
+                    # remove the argument and the trailing or preceeding comma
+                    if i == n_children - 1:  # last argument
+                        args[0].children[i - 1].remove()
+                        args[0].children[i - 1].remove()
+                    else:
+                        args[0].children[i].remove()
+                        args[0].children[i].remove()
+
+                    break
+        else:  # there's only one argument
+            args[0].remove()
+
+
 def bitcoin_to_crypto(query):
     return (
         query
         .select_class("BitcoinTicker")
+        .modify(reset_format)
         .rename("CryptoTicker")
     )
 


Test patch:
diff --git a/test/test_migrate.py b/test/test_migrate.py
--- a/test/test_migrate.py
+++ b/test/test_migrate.py
@@ -174,14 +174,30 @@ def test_crypto():
         from libqtile import bar
         from libqtile.widget import BitcoinTicker
 
-        bar.Bar([BitcoinTicker()], 30)
+        bar.Bar(
+            [
+                BitcoinTicker(crypto='BTC', format='BTC: {avg}'),
+                BitcoinTicker(format='{crypto}: {avg}', font='sans'),
+                BitcoinTicker(),
+                BitcoinTicker(currency='EUR', format='{avg}', foreground='ffffff'),
+            ],
+            30
+        )
     """)
 
     expected = textwrap.dedent("""
         from libqtile import bar
         from libqtile.widget import CryptoTicker
 
-        bar.Bar([CryptoTicker()], 30)
+        bar.Bar(
+            [
+                CryptoTicker(crypto='BTC'),
+                CryptoTicker( font='sans'),
+                CryptoTicker(),
+                CryptoTicker(currency='EUR', foreground='ffffff'),
+            ],
+            30
+        )
     """)
 
     check_migrate(orig, expected)