We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
qtile-top crash 'Client' object has no attribute 'tracemalloc_dump'
<!--
Please do not ask general questions here! There are [community
contact](https://github.com/qtile/qtile#community) options for that.
-->

# Issue description

<!--
A brief discussion of what failed and how it failed. A description of
what you tried is helpful, i.e. "When I use lazy.kill() on a window I get
the following stack trace" instead of "Closing windows doesn't work".
-->
Tried to run `qtile-top` and it crashed. I'm not sure should be done before that script  - no documentation.
Tried 
```
 arnas@zordmachine  ~  qtile-cmd -o cmd -f tracemalloc_dump
[False, 'Trace not started']
 arnas@zordmachine  ~  qtile-cmd -o cmd -f tracemalloc_toggle
 arnas@zordmachine  ~  qtile-cmd -o cmd -f tracemalloc_dump
[True, '/home/arnas/.cache/qtile/qtile_tracemalloc.dump']
```
but this didn't helped

# Qtile version

<!--
Please include the exact commit hash of the version of Qtile that failed.
-->

5bd8e57f78b72ed9de4d10bf51af6db51561d794 (latest git version)

# Stack traces

<!--
Please attach any stack traces found in:

* `~/.xsession-errors`
* `~/.local/share/qtile/qtile.log`
-->

Traceback (most recent call last):
  File "/usr/bin/qtile-top", line 11, in <module>
    load_entry_point('qtile==0.15.0', 'console_scripts', 'qtile-top')()
  File "/usr/lib/python3.8/site-packages/libqtile/scripts/qtile_top.py", line 164, in main
    curses.wrapper(get_stats, client, limit=lines, seconds=seconds,
  File "/usr/lib/python3.8/curses/__init__.py", line 105, in wrapper
    return func(stdscr, *args, **kwds)
  File "/usr/lib/python3.8/site-packages/libqtile/scripts/qtile_top.py", line 91, in get_stats
    snapshot = get_trace(client, force_start)
  File "/usr/lib/python3.8/site-packages/libqtile/scripts/qtile_top.py", line 63, in get_trace
    (started, path) = client.tracemalloc_dump()
AttributeError: 'Client' object has no attribute 'tracemalloc_dump'


# Configuration

<!--
Please include a link or attach your configuration to the issue.
-->
https://github.com/zordsdavini/qtile-config
Arch
qtile-top crash 'Client' object has no attribute 'tracemalloc_dump'
<!--
Please do not ask general questions here! There are [community
contact](https://github.com/qtile/qtile#community) options for that.
-->

# Issue description

<!--
A brief discussion of what failed and how it failed. A description of
what you tried is helpful, i.e. "When I use lazy.kill() on a window I get
the following stack trace" instead of "Closing windows doesn't work".
-->
Tried to run `qtile-top` and it crashed. I'm not sure should be done before that script  - no documentation.
Tried 
```
 arnas@zordmachine  ~  qtile-cmd -o cmd -f tracemalloc_dump
[False, 'Trace not started']
 arnas@zordmachine  ~  qtile-cmd -o cmd -f tracemalloc_toggle
 arnas@zordmachine  ~  qtile-cmd -o cmd -f tracemalloc_dump
[True, '/home/arnas/.cache/qtile/qtile_tracemalloc.dump']
```
but this didn't helped

# Qtile version

<!--
Please include the exact commit hash of the version of Qtile that failed.
-->

5bd8e57f78b72ed9de4d10bf51af6db51561d794 (latest git version)

# Stack traces

<!--
Please attach any stack traces found in:

* `~/.xsession-errors`
* `~/.local/share/qtile/qtile.log`
-->

Traceback (most recent call last):
  File "/usr/bin/qtile-top", line 11, in <module>
    load_entry_point('qtile==0.15.0', 'console_scripts', 'qtile-top')()
  File "/usr/lib/python3.8/site-packages/libqtile/scripts/qtile_top.py", line 164, in main
    curses.wrapper(get_stats, client, limit=lines, seconds=seconds,
  File "/usr/lib/python3.8/curses/__init__.py", line 105, in wrapper
    return func(stdscr, *args, **kwds)
  File "/usr/lib/python3.8/site-packages/libqtile/scripts/qtile_top.py", line 91, in get_stats
    snapshot = get_trace(client, force_start)
  File "/usr/lib/python3.8/site-packages/libqtile/scripts/qtile_top.py", line 63, in get_trace
    (started, path) = client.tracemalloc_dump()
AttributeError: 'Client' object has no attribute 'tracemalloc_dump'


# Configuration

<!--
Please include a link or attach your configuration to the issue.
-->
https://github.com/zordsdavini/qtile-config
Arch

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `libqtile/scripts/qtile_top.py`
Content:
```
1 # Copyright (c) 2015, Roger Duran
2 #
3 # Permission is hereby granted, free of charge, to any person obtaining a copy
4 # of this software and associated documentation files (the "Software"), to deal
5 # in the Software without restriction, including without limitation the rights
6 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 # copies of the Software, and to permit persons to whom the Software is
8 # furnished to do so, subject to the following conditions:
9 #
10 # The above copyright notice and this permission notice shall be included in
11 # all copies or substantial portions of the Software.
12 #
13 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 # SOFTWARE.
20 
21 """
22     Command-line top like for qtile
23 """
24 
25 import argparse
26 import curses
27 import linecache
28 import os
29 import time
30 import tracemalloc
31 from tracemalloc import Snapshot
32 
33 from libqtile import ipc
34 
35 
36 class TraceNotStarted(Exception):
37     pass
38 
39 
40 class TraceCantStart(Exception):
41     pass
42 
43 
44 def parse_args():
45     parser = argparse.ArgumentParser(description="Top like for qtile")
46     parser.add_argument('-l', '--lines', type=int, dest="lines", default=10,
47                         help='Number of lines.')
48     parser.add_argument('-r', '--raw', dest="raw", action="store_true",
49                         default=False, help='Output raw without curses')
50     parser.add_argument('-t', '--time', type=float, dest="seconds",
51                         default=1.5, help='Number of seconds to refresh')
52     parser.add_argument('--force-start', dest="force_start",
53                         action="store_true", default=False,
54                         help='Force start tracemalloc on qtile')
55     parser.add_argument('-s', '--socket', type=str, dest="socket",
56                         help='Use specified communication socket.')
57 
58     opts = parser.parse_args()
59     return opts
60 
61 
62 def get_trace(client, force_start):
63     (started, path) = client.tracemalloc_dump()
64     if force_start and not started:
65         client.tracemalloc_toggle()
66         (started, path) = client.tracemalloc_dump()
67         if not started:
68             raise TraceCantStart
69     elif not started:
70         raise TraceNotStarted
71 
72     return Snapshot.load(path)
73 
74 
75 def filter_snapshot(snapshot):
76     return snapshot.filter_traces((
77         tracemalloc.Filter(False, "<frozen importlib._bootstrap>"),
78         tracemalloc.Filter(False, "<unknown>"),
79     ))
80 
81 
82 def get_stats(scr, client, group_by='lineno', limit=10, seconds=1.5,
83               force_start=False):
84     (max_y, max_x) = scr.getmaxyx()
85     curses.init_pair(1, curses.COLOR_GREEN, curses.COLOR_BLACK)
86     while True:
87         scr.addstr(0, 0, "Qtile - Top {} lines".format(limit))
88         scr.addstr(1, 0, '{0:<3s} {1:<40s} {2:<30s} {3:<16s}'.format('#', 'Line', 'Memory', ' ' * (max_x - 71)),
89                    curses.A_BOLD | curses.A_REVERSE)
90 
91         snapshot = get_trace(client, force_start)
92         snapshot = filter_snapshot(snapshot)
93         top_stats = snapshot.statistics(group_by)
94         cnt = 1
95         for index, stat in enumerate(top_stats[:limit], 1):
96             frame = stat.traceback[0]
97             # replace "/path/to/module/file.py" with "module/file.py"
98             filename = os.sep.join(frame.filename.split(os.sep)[-2:])
99             code = ""
100             line = linecache.getline(frame.filename, frame.lineno).strip()
101             if line:
102                 code = line
103             mem = "{:.1f} KiB".format(stat.size / 1024.0)
104             filename = "{}:{}".format(filename, frame.lineno)
105             scr.addstr(cnt + 1, 0, '{:<3} {:<40} {:<30}'.format(index, filename, mem))
106             scr.addstr(cnt + 2, 4, code, curses.color_pair(1))
107             cnt += 2
108 
109         other = top_stats[limit:]
110         cnt += 2
111         if other:
112             size = sum(stat.size for stat in other)
113             other_size = ("{:d} other: {:.1f} KiB".format(len(other), size / 1024.0))
114             scr.addstr(cnt, 0, other_size, curses.A_BOLD)
115             cnt += 1
116 
117         total = sum(stat.size for stat in top_stats)
118         total_size = "Total allocated size: {0:.1f} KiB".format(total / 1024.0)
119         scr.addstr(cnt, 0, total_size, curses.A_BOLD)
120 
121         scr.move(max_y - 2, max_y - 2)
122         scr.refresh()
123         time.sleep(seconds)
124         scr.erase()
125 
126 
127 def raw_stats(client, group_by='lineno', limit=10, force_start=False):
128     snapshot = get_trace(client, force_start)
129     snapshot = filter_snapshot(snapshot)
130     top_stats = snapshot.statistics(group_by)
131 
132     print("Qtile - Top {} lines".format(limit))
133     for index, stat in enumerate(top_stats[:limit], 1):
134         frame = stat.traceback[0]
135         # replace "/path/to/module/file.py" with "module/file.py"
136         filename = os.sep.join(frame.filename.split(os.sep)[-2:])
137         print("#{}: {}:{}: {:.1f} KiB"
138               .format(index, filename, frame.lineno, stat.size / 1024.0))
139         line = linecache.getline(frame.filename, frame.lineno).strip()
140         if line:
141             print('    {}'.format(line))
142 
143     other = top_stats[limit:]
144     if other:
145         size = sum(stat.size for stat in other)
146         print("{:d} other: {:.1f} KiB".format(len(other), size / 1024.0))
147     total = sum(stat.size for stat in top_stats)
148     print("Total allocated size: {0:.1f} KiB".format(total / 1024.0))
149 
150 
151 def main():
152     opts = parse_args()
153     lines = opts.lines
154     seconds = opts.seconds
155     force_start = opts.force_start
156     if opts.socket is None:
157         socket = ipc.find_sockfile()
158     else:
159         socket = opts.socket
160     client = ipc.Client(socket)
161 
162     try:
163         if not opts.raw:
164             curses.wrapper(get_stats, client, limit=lines, seconds=seconds,
165                            force_start=force_start)
166         else:
167             raw_stats(client, limit=lines, force_start=force_start)
168     except TraceNotStarted:
169         print("tracemalloc not started on qtile, start by setting "
170               "PYTHONTRACEMALLOC=1 before starting qtile")
171         print("or force start tracemalloc now, but you'll lose early traces")
172         exit(1)
173     except TraceCantStart:
174         print("Can't start tracemalloc on qtile, check the logs")
175     except KeyboardInterrupt:
176         exit(-1)
177
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/libqtile/scripts/qtile_top.py b/libqtile/scripts/qtile_top.py
--- a/libqtile/scripts/qtile_top.py
+++ b/libqtile/scripts/qtile_top.py
@@ -30,7 +30,7 @@
 import tracemalloc
 from tracemalloc import Snapshot
 
-from libqtile import ipc
+from libqtile import command_client, command_interface, ipc
 
 
 class TraceNotStarted(Exception):
@@ -158,6 +158,8 @@
     else:
         socket = opts.socket
     client = ipc.Client(socket)
+    client = command_interface.IPCCommandInterface(client)
+    client = command_client.InteractiveCommandClient(client)
 
     try:
         if not opts.raw:

{"golden_diff": "diff --git a/libqtile/scripts/qtile_top.py b/libqtile/scripts/qtile_top.py\n--- a/libqtile/scripts/qtile_top.py\n+++ b/libqtile/scripts/qtile_top.py\n@@ -30,7 +30,7 @@\n import tracemalloc\n from tracemalloc import Snapshot\n \n-from libqtile import ipc\n+from libqtile import command_client, command_interface, ipc\n \n \n class TraceNotStarted(Exception):\n@@ -158,6 +158,8 @@\n     else:\n         socket = opts.socket\n     client = ipc.Client(socket)\n+    client = command_interface.IPCCommandInterface(client)\n+    client = command_client.InteractiveCommandClient(client)\n \n     try:\n         if not opts.raw:\n", "issue": "qtile-top crash 'Client' object has no attribute 'tracemalloc_dump'\n<!--\r\nPlease do not ask general questions here! There are [community\r\ncontact](https://github.com/qtile/qtile#community) options for that.\r\n-->\r\n\r\n# Issue description\r\n\r\n<!--\r\nA brief discussion of what failed and how it failed. A description of\r\nwhat you tried is helpful, i.e. \"When I use lazy.kill() on a window I get\r\nthe following stack trace\" instead of \"Closing windows doesn't work\".\r\n-->\r\nTried to run `qtile-top` and it crashed. I'm not sure should be done before that script  - no documentation.\r\nTried \r\n```\r\n arnas@zordmachine \ue0b0 ~ \ue0b0 qtile-cmd -o cmd -f tracemalloc_dump\r\n[False, 'Trace not started']\r\n arnas@zordmachine \ue0b0 ~ \ue0b0 qtile-cmd -o cmd -f tracemalloc_toggle\r\n arnas@zordmachine \ue0b0 ~ \ue0b0 qtile-cmd -o cmd -f tracemalloc_dump\r\n[True, '/home/arnas/.cache/qtile/qtile_tracemalloc.dump']\r\n```\r\nbut this didn't helped\r\n\r\n# Qtile version\r\n\r\n<!--\r\nPlease include the exact commit hash of the version of Qtile that failed.\r\n-->\r\n\r\n5bd8e57f78b72ed9de4d10bf51af6db51561d794 (latest git version)\r\n\r\n# Stack traces\r\n\r\n<!--\r\nPlease attach any stack traces found in:\r\n\r\n* `~/.xsession-errors`\r\n* `~/.local/share/qtile/qtile.log`\r\n-->\r\n\r\nTraceback (most recent call last):\r\n  File \"/usr/bin/qtile-top\", line 11, in <module>\r\n    load_entry_point('qtile==0.15.0', 'console_scripts', 'qtile-top')()\r\n  File \"/usr/lib/python3.8/site-packages/libqtile/scripts/qtile_top.py\", line 164, in main\r\n    curses.wrapper(get_stats, client, limit=lines, seconds=seconds,\r\n  File \"/usr/lib/python3.8/curses/__init__.py\", line 105, in wrapper\r\n    return func(stdscr, *args, **kwds)\r\n  File \"/usr/lib/python3.8/site-packages/libqtile/scripts/qtile_top.py\", line 91, in get_stats\r\n    snapshot = get_trace(client, force_start)\r\n  File \"/usr/lib/python3.8/site-packages/libqtile/scripts/qtile_top.py\", line 63, in get_trace\r\n    (started, path) = client.tracemalloc_dump()\r\nAttributeError: 'Client' object has no attribute 'tracemalloc_dump'\r\n\r\n\r\n# Configuration\r\n\r\n<!--\r\nPlease include a link or attach your configuration to the issue.\r\n-->\r\nhttps://github.com/zordsdavini/qtile-config\r\nArch\nqtile-top crash 'Client' object has no attribute 'tracemalloc_dump'\n<!--\r\nPlease do not ask general questions here! There are [community\r\ncontact](https://github.com/qtile/qtile#community) options for that.\r\n-->\r\n\r\n# Issue description\r\n\r\n<!--\r\nA brief discussion of what failed and how it failed. A description of\r\nwhat you tried is helpful, i.e. \"When I use lazy.kill() on a window I get\r\nthe following stack trace\" instead of \"Closing windows doesn't work\".\r\n-->\r\nTried to run `qtile-top` and it crashed. I'm not sure should be done before that script  - no documentation.\r\nTried \r\n```\r\n arnas@zordmachine \ue0b0 ~ \ue0b0 qtile-cmd -o cmd -f tracemalloc_dump\r\n[False, 'Trace not started']\r\n arnas@zordmachine \ue0b0 ~ \ue0b0 qtile-cmd -o cmd -f tracemalloc_toggle\r\n arnas@zordmachine \ue0b0 ~ \ue0b0 qtile-cmd -o cmd -f tracemalloc_dump\r\n[True, '/home/arnas/.cache/qtile/qtile_tracemalloc.dump']\r\n```\r\nbut this didn't helped\r\n\r\n# Qtile version\r\n\r\n<!--\r\nPlease include the exact commit hash of the version of Qtile that failed.\r\n-->\r\n\r\n5bd8e57f78b72ed9de4d10bf51af6db51561d794 (latest git version)\r\n\r\n# Stack traces\r\n\r\n<!--\r\nPlease attach any stack traces found in:\r\n\r\n* `~/.xsession-errors`\r\n* `~/.local/share/qtile/qtile.log`\r\n-->\r\n\r\nTraceback (most recent call last):\r\n  File \"/usr/bin/qtile-top\", line 11, in <module>\r\n    load_entry_point('qtile==0.15.0', 'console_scripts', 'qtile-top')()\r\n  File \"/usr/lib/python3.8/site-packages/libqtile/scripts/qtile_top.py\", line 164, in main\r\n    curses.wrapper(get_stats, client, limit=lines, seconds=seconds,\r\n  File \"/usr/lib/python3.8/curses/__init__.py\", line 105, in wrapper\r\n    return func(stdscr, *args, **kwds)\r\n  File \"/usr/lib/python3.8/site-packages/libqtile/scripts/qtile_top.py\", line 91, in get_stats\r\n    snapshot = get_trace(client, force_start)\r\n  File \"/usr/lib/python3.8/site-packages/libqtile/scripts/qtile_top.py\", line 63, in get_trace\r\n    (started, path) = client.tracemalloc_dump()\r\nAttributeError: 'Client' object has no attribute 'tracemalloc_dump'\r\n\r\n\r\n# Configuration\r\n\r\n<!--\r\nPlease include a link or attach your configuration to the issue.\r\n-->\r\nhttps://github.com/zordsdavini/qtile-config\r\nArch\n", "before_files": [{"content": "# Copyright (c) 2015, Roger Duran\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n\n\"\"\"\n    Command-line top like for qtile\n\"\"\"\n\nimport argparse\nimport curses\nimport linecache\nimport os\nimport time\nimport tracemalloc\nfrom tracemalloc import Snapshot\n\nfrom libqtile import ipc\n\n\nclass TraceNotStarted(Exception):\n    pass\n\n\nclass TraceCantStart(Exception):\n    pass\n\n\ndef parse_args():\n    parser = argparse.ArgumentParser(description=\"Top like for qtile\")\n    parser.add_argument('-l', '--lines', type=int, dest=\"lines\", default=10,\n                        help='Number of lines.')\n    parser.add_argument('-r', '--raw', dest=\"raw\", action=\"store_true\",\n                        default=False, help='Output raw without curses')\n    parser.add_argument('-t', '--time', type=float, dest=\"seconds\",\n                        default=1.5, help='Number of seconds to refresh')\n    parser.add_argument('--force-start', dest=\"force_start\",\n                        action=\"store_true\", default=False,\n                        help='Force start tracemalloc on qtile')\n    parser.add_argument('-s', '--socket', type=str, dest=\"socket\",\n                        help='Use specified communication socket.')\n\n    opts = parser.parse_args()\n    return opts\n\n\ndef get_trace(client, force_start):\n    (started, path) = client.tracemalloc_dump()\n    if force_start and not started:\n        client.tracemalloc_toggle()\n        (started, path) = client.tracemalloc_dump()\n        if not started:\n            raise TraceCantStart\n    elif not started:\n        raise TraceNotStarted\n\n    return Snapshot.load(path)\n\n\ndef filter_snapshot(snapshot):\n    return snapshot.filter_traces((\n        tracemalloc.Filter(False, \"<frozen importlib._bootstrap>\"),\n        tracemalloc.Filter(False, \"<unknown>\"),\n    ))\n\n\ndef get_stats(scr, client, group_by='lineno', limit=10, seconds=1.5,\n              force_start=False):\n    (max_y, max_x) = scr.getmaxyx()\n    curses.init_pair(1, curses.COLOR_GREEN, curses.COLOR_BLACK)\n    while True:\n        scr.addstr(0, 0, \"Qtile - Top {} lines\".format(limit))\n        scr.addstr(1, 0, '{0:<3s} {1:<40s} {2:<30s} {3:<16s}'.format('#', 'Line', 'Memory', ' ' * (max_x - 71)),\n                   curses.A_BOLD | curses.A_REVERSE)\n\n        snapshot = get_trace(client, force_start)\n        snapshot = filter_snapshot(snapshot)\n        top_stats = snapshot.statistics(group_by)\n        cnt = 1\n        for index, stat in enumerate(top_stats[:limit], 1):\n            frame = stat.traceback[0]\n            # replace \"/path/to/module/file.py\" with \"module/file.py\"\n            filename = os.sep.join(frame.filename.split(os.sep)[-2:])\n            code = \"\"\n            line = linecache.getline(frame.filename, frame.lineno).strip()\n            if line:\n                code = line\n            mem = \"{:.1f} KiB\".format(stat.size / 1024.0)\n            filename = \"{}:{}\".format(filename, frame.lineno)\n            scr.addstr(cnt + 1, 0, '{:<3} {:<40} {:<30}'.format(index, filename, mem))\n            scr.addstr(cnt + 2, 4, code, curses.color_pair(1))\n            cnt += 2\n\n        other = top_stats[limit:]\n        cnt += 2\n        if other:\n            size = sum(stat.size for stat in other)\n            other_size = (\"{:d} other: {:.1f} KiB\".format(len(other), size / 1024.0))\n            scr.addstr(cnt, 0, other_size, curses.A_BOLD)\n            cnt += 1\n\n        total = sum(stat.size for stat in top_stats)\n        total_size = \"Total allocated size: {0:.1f} KiB\".format(total / 1024.0)\n        scr.addstr(cnt, 0, total_size, curses.A_BOLD)\n\n        scr.move(max_y - 2, max_y - 2)\n        scr.refresh()\n        time.sleep(seconds)\n        scr.erase()\n\n\ndef raw_stats(client, group_by='lineno', limit=10, force_start=False):\n    snapshot = get_trace(client, force_start)\n    snapshot = filter_snapshot(snapshot)\n    top_stats = snapshot.statistics(group_by)\n\n    print(\"Qtile - Top {} lines\".format(limit))\n    for index, stat in enumerate(top_stats[:limit], 1):\n        frame = stat.traceback[0]\n        # replace \"/path/to/module/file.py\" with \"module/file.py\"\n        filename = os.sep.join(frame.filename.split(os.sep)[-2:])\n        print(\"#{}: {}:{}: {:.1f} KiB\"\n              .format(index, filename, frame.lineno, stat.size / 1024.0))\n        line = linecache.getline(frame.filename, frame.lineno).strip()\n        if line:\n            print('    {}'.format(line))\n\n    other = top_stats[limit:]\n    if other:\n        size = sum(stat.size for stat in other)\n        print(\"{:d} other: {:.1f} KiB\".format(len(other), size / 1024.0))\n    total = sum(stat.size for stat in top_stats)\n    print(\"Total allocated size: {0:.1f} KiB\".format(total / 1024.0))\n\n\ndef main():\n    opts = parse_args()\n    lines = opts.lines\n    seconds = opts.seconds\n    force_start = opts.force_start\n    if opts.socket is None:\n        socket = ipc.find_sockfile()\n    else:\n        socket = opts.socket\n    client = ipc.Client(socket)\n\n    try:\n        if not opts.raw:\n            curses.wrapper(get_stats, client, limit=lines, seconds=seconds,\n                           force_start=force_start)\n        else:\n            raw_stats(client, limit=lines, force_start=force_start)\n    except TraceNotStarted:\n        print(\"tracemalloc not started on qtile, start by setting \"\n              \"PYTHONTRACEMALLOC=1 before starting qtile\")\n        print(\"or force start tracemalloc now, but you'll lose early traces\")\n        exit(1)\n    except TraceCantStart:\n        print(\"Can't start tracemalloc on qtile, check the logs\")\n    except KeyboardInterrupt:\n        exit(-1)\n", "path": "libqtile/scripts/qtile_top.py"}], "after_files": [{"content": "# Copyright (c) 2015, Roger Duran\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n\n\"\"\"\n    Command-line top like for qtile\n\"\"\"\n\nimport argparse\nimport curses\nimport linecache\nimport os\nimport time\nimport tracemalloc\nfrom tracemalloc import Snapshot\n\nfrom libqtile import command_client, command_interface, ipc\n\n\nclass TraceNotStarted(Exception):\n    pass\n\n\nclass TraceCantStart(Exception):\n    pass\n\n\ndef parse_args():\n    parser = argparse.ArgumentParser(description=\"Top like for qtile\")\n    parser.add_argument('-l', '--lines', type=int, dest=\"lines\", default=10,\n                        help='Number of lines.')\n    parser.add_argument('-r', '--raw', dest=\"raw\", action=\"store_true\",\n                        default=False, help='Output raw without curses')\n    parser.add_argument('-t', '--time', type=float, dest=\"seconds\",\n                        default=1.5, help='Number of seconds to refresh')\n    parser.add_argument('--force-start', dest=\"force_start\",\n                        action=\"store_true\", default=False,\n                        help='Force start tracemalloc on qtile')\n    parser.add_argument('-s', '--socket', type=str, dest=\"socket\",\n                        help='Use specified communication socket.')\n\n    opts = parser.parse_args()\n    return opts\n\n\ndef get_trace(client, force_start):\n    (started, path) = client.tracemalloc_dump()\n    if force_start and not started:\n        client.tracemalloc_toggle()\n        (started, path) = client.tracemalloc_dump()\n        if not started:\n            raise TraceCantStart\n    elif not started:\n        raise TraceNotStarted\n\n    return Snapshot.load(path)\n\n\ndef filter_snapshot(snapshot):\n    return snapshot.filter_traces((\n        tracemalloc.Filter(False, \"<frozen importlib._bootstrap>\"),\n        tracemalloc.Filter(False, \"<unknown>\"),\n    ))\n\n\ndef get_stats(scr, client, group_by='lineno', limit=10, seconds=1.5,\n              force_start=False):\n    (max_y, max_x) = scr.getmaxyx()\n    curses.init_pair(1, curses.COLOR_GREEN, curses.COLOR_BLACK)\n    while True:\n        scr.addstr(0, 0, \"Qtile - Top {} lines\".format(limit))\n        scr.addstr(1, 0, '{0:<3s} {1:<40s} {2:<30s} {3:<16s}'.format('#', 'Line', 'Memory', ' ' * (max_x - 71)),\n                   curses.A_BOLD | curses.A_REVERSE)\n\n        snapshot = get_trace(client, force_start)\n        snapshot = filter_snapshot(snapshot)\n        top_stats = snapshot.statistics(group_by)\n        cnt = 1\n        for index, stat in enumerate(top_stats[:limit], 1):\n            frame = stat.traceback[0]\n            # replace \"/path/to/module/file.py\" with \"module/file.py\"\n            filename = os.sep.join(frame.filename.split(os.sep)[-2:])\n            code = \"\"\n            line = linecache.getline(frame.filename, frame.lineno).strip()\n            if line:\n                code = line\n            mem = \"{:.1f} KiB\".format(stat.size / 1024.0)\n            filename = \"{}:{}\".format(filename, frame.lineno)\n            scr.addstr(cnt + 1, 0, '{:<3} {:<40} {:<30}'.format(index, filename, mem))\n            scr.addstr(cnt + 2, 4, code, curses.color_pair(1))\n            cnt += 2\n\n        other = top_stats[limit:]\n        cnt += 2\n        if other:\n            size = sum(stat.size for stat in other)\n            other_size = (\"{:d} other: {:.1f} KiB\".format(len(other), size / 1024.0))\n            scr.addstr(cnt, 0, other_size, curses.A_BOLD)\n            cnt += 1\n\n        total = sum(stat.size for stat in top_stats)\n        total_size = \"Total allocated size: {0:.1f} KiB\".format(total / 1024.0)\n        scr.addstr(cnt, 0, total_size, curses.A_BOLD)\n\n        scr.move(max_y - 2, max_y - 2)\n        scr.refresh()\n        time.sleep(seconds)\n        scr.erase()\n\n\ndef raw_stats(client, group_by='lineno', limit=10, force_start=False):\n    snapshot = get_trace(client, force_start)\n    snapshot = filter_snapshot(snapshot)\n    top_stats = snapshot.statistics(group_by)\n\n    print(\"Qtile - Top {} lines\".format(limit))\n    for index, stat in enumerate(top_stats[:limit], 1):\n        frame = stat.traceback[0]\n        # replace \"/path/to/module/file.py\" with \"module/file.py\"\n        filename = os.sep.join(frame.filename.split(os.sep)[-2:])\n        print(\"#{}: {}:{}: {:.1f} KiB\"\n              .format(index, filename, frame.lineno, stat.size / 1024.0))\n        line = linecache.getline(frame.filename, frame.lineno).strip()\n        if line:\n            print('    {}'.format(line))\n\n    other = top_stats[limit:]\n    if other:\n        size = sum(stat.size for stat in other)\n        print(\"{:d} other: {:.1f} KiB\".format(len(other), size / 1024.0))\n    total = sum(stat.size for stat in top_stats)\n    print(\"Total allocated size: {0:.1f} KiB\".format(total / 1024.0))\n\n\ndef main():\n    opts = parse_args()\n    lines = opts.lines\n    seconds = opts.seconds\n    force_start = opts.force_start\n    if opts.socket is None:\n        socket = ipc.find_sockfile()\n    else:\n        socket = opts.socket\n    client = ipc.Client(socket)\n    client = command_interface.IPCCommandInterface(client)\n    client = command_client.InteractiveCommandClient(client)\n\n    try:\n        if not opts.raw:\n            curses.wrapper(get_stats, client, limit=lines, seconds=seconds,\n                           force_start=force_start)\n        else:\n            raw_stats(client, limit=lines, force_start=force_start)\n    except TraceNotStarted:\n        print(\"tracemalloc not started on qtile, start by setting \"\n              \"PYTHONTRACEMALLOC=1 before starting qtile\")\n        print(\"or force start tracemalloc now, but you'll lose early traces\")\n        exit(1)\n    except TraceCantStart:\n        print(\"Can't start tracemalloc on qtile, check the logs\")\n    except KeyboardInterrupt:\n        exit(-1)\n", "path": "libqtile/scripts/qtile_top.py"}]}