We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
No filename provided Image widget causes QTile to crash.
# The issue
When no filename argument, OR an invalid filename is provided for the Image widget, Qtile seems to crash, and needs to be killed to restart. You are obviously not supposed to provide a non-existant image, but I have doubts that it crashing is intended behavior. 

What I am describing here as a "crash" is no keyboard input being accepted, and windows from *all* other workspaces being displayed on the workspace you are currently on. If this is not actually a crash, I apologize, but regardless, Qtile becomes unusable until the process is killed and I am kicked back to my Display Manager.

# Steps to reproduce
In your bar, create a new ``Image`` widget somewhere inside. Either provide a path to an image that does not exist, or do not provide one period.

# Qtile version
This is the commit hash of the version I am running.
6c4d0557124989d46ffb2bb24f4468db687fcdb2

# Stack traces
No stack traces from xsession-errors, or the Qtile log are produced, however I have traced the error (through using the logger provided in the module's file) to the ``_configure`` method of the Image widget, and it seems to be coming the line: ``base._Widget._configure(self, qtile, bar)``

# Configuration
https://pastebin.com/qxBq6yPn

If there is any information I got wrong here, or some other bit of information I can provide that will help this issue get solved, I will try my best.

--- 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/widget/image.py`
Content:
```
1 # Copyright (c) 2013 dequis
2 # Copyright (c) 2014 Sean Vig
3 # Copyright (c) 2014 Adi Sieker
4 #
5 # Permission is hereby granted, free of charge, to any person obtaining a copy
6 # of this software and associated documentation files (the "Software"), to deal
7 # in the Software without restriction, including without limitation the rights
8 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 # copies of the Software, and to permit persons to whom the Software is
10 # furnished to do so, subject to the following conditions:
11 #
12 # The above copyright notice and this permission notice shall be included in
13 # all copies or substantial portions of the Software.
14 #
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 # SOFTWARE.
22 import os
23 
24 from libqtile import bar
25 from libqtile.images import Img
26 from libqtile.log_utils import logger
27 from libqtile.widget import base
28 
29 
30 class Image(base._Widget, base.MarginMixin):
31     """Display a PNG image on the bar"""
32     orientations = base.ORIENTATION_BOTH
33     defaults = [
34         ("scale", True, "Enable/Disable image scaling"),
35         ("rotate", 0.0, "rotate the image in degrees counter-clockwise"),
36         ("filename", None, "Image filename. Can contain '~'"),
37     ]
38 
39     def __init__(self, length=bar.CALCULATED, width=None, **config):
40         # 'width' was replaced by 'length' since the widget can be installed in
41         # vertical bars
42         if width is not None:
43             logger.warning('width kwarg or positional argument is '
44                            'deprecated. Please use length.')
45             length = width
46 
47         base._Widget.__init__(self, length, **config)
48         self.add_defaults(Image.defaults)
49         self.add_defaults(base.MarginMixin.defaults)
50 
51         # make the default 0 instead
52         self._variable_defaults["margin"] = 0
53 
54     def _configure(self, qtile, bar):
55         base._Widget._configure(self, qtile, bar)
56 
57         if not self.filename:
58             raise ValueError("Filename not set!")
59 
60         self.filename = os.path.expanduser(self.filename)
61 
62         if not os.path.exists(self.filename):
63             raise ValueError("File does not exist: {}".format(self.filename))
64 
65         img = Img.from_path(self.filename)
66         self.img = img
67         img.theta = self.rotate
68         if not self.scale:
69             return
70         if self.bar.horizontal:
71             new_height = self.bar.height - (self.margin_y * 2)
72             img.resize(height=new_height)
73         else:
74             new_width = self.bar.width - (self.margin_x * 2)
75             img.resize(width=new_width)
76 
77     def draw(self):
78         self.drawer.clear(self.background or self.bar.background)
79         self.drawer.ctx.save()
80         self.drawer.ctx.translate(self.margin_x, self.margin_y)
81         self.drawer.ctx.set_source(self.img.pattern)
82         self.drawer.ctx.paint()
83         self.drawer.ctx.restore()
84 
85         if self.bar.horizontal:
86             self.drawer.draw(offsetx=self.offset, width=self.width)
87         else:
88             self.drawer.draw(offsety=self.offset, height=self.width)
89 
90     def calculate_length(self):
91         if self.bar.horizontal:
92             return self.img.width + (self.margin_x * 2)
93         else:
94             return self.img.height + (self.margin_y * 2)
95
```
--- 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/widget/image.py b/libqtile/widget/image.py
--- a/libqtile/widget/image.py
+++ b/libqtile/widget/image.py
@@ -53,14 +53,17 @@
 
     def _configure(self, qtile, bar):
         base._Widget._configure(self, qtile, bar)
+        self.img = None
 
         if not self.filename:
-            raise ValueError("Filename not set!")
+            logger.warning("Image filename not set!")
+            return
 
         self.filename = os.path.expanduser(self.filename)
 
         if not os.path.exists(self.filename):
-            raise ValueError("File does not exist: {}".format(self.filename))
+            logger.warning("Image does not exist: {}".format(self.filename))
+            return
 
         img = Img.from_path(self.filename)
         self.img = img
@@ -75,6 +78,9 @@
             img.resize(width=new_width)
 
     def draw(self):
+        if self.img is None:
+            return
+
         self.drawer.clear(self.background or self.bar.background)
         self.drawer.ctx.save()
         self.drawer.ctx.translate(self.margin_x, self.margin_y)
@@ -88,6 +94,9 @@
             self.drawer.draw(offsety=self.offset, height=self.width)
 
     def calculate_length(self):
+        if self.img is None:
+            return 0
+
         if self.bar.horizontal:
             return self.img.width + (self.margin_x * 2)
         else:

{"golden_diff": "diff --git a/libqtile/widget/image.py b/libqtile/widget/image.py\n--- a/libqtile/widget/image.py\n+++ b/libqtile/widget/image.py\n@@ -53,14 +53,17 @@\n \n     def _configure(self, qtile, bar):\n         base._Widget._configure(self, qtile, bar)\n+        self.img = None\n \n         if not self.filename:\n-            raise ValueError(\"Filename not set!\")\n+            logger.warning(\"Image filename not set!\")\n+            return\n \n         self.filename = os.path.expanduser(self.filename)\n \n         if not os.path.exists(self.filename):\n-            raise ValueError(\"File does not exist: {}\".format(self.filename))\n+            logger.warning(\"Image does not exist: {}\".format(self.filename))\n+            return\n \n         img = Img.from_path(self.filename)\n         self.img = img\n@@ -75,6 +78,9 @@\n             img.resize(width=new_width)\n \n     def draw(self):\n+        if self.img is None:\n+            return\n+\n         self.drawer.clear(self.background or self.bar.background)\n         self.drawer.ctx.save()\n         self.drawer.ctx.translate(self.margin_x, self.margin_y)\n@@ -88,6 +94,9 @@\n             self.drawer.draw(offsety=self.offset, height=self.width)\n \n     def calculate_length(self):\n+        if self.img is None:\n+            return 0\n+\n         if self.bar.horizontal:\n             return self.img.width + (self.margin_x * 2)\n         else:\n", "issue": "No filename provided Image widget causes QTile to crash.\n# The issue\r\nWhen no filename argument, OR an invalid filename is provided for the Image widget, Qtile seems to crash, and needs to be killed to restart. You are obviously not supposed to provide a non-existant image, but I have doubts that it crashing is intended behavior. \r\n\r\nWhat I am describing here as a \"crash\" is no keyboard input being accepted, and windows from *all* other workspaces being displayed on the workspace you are currently on. If this is not actually a crash, I apologize, but regardless, Qtile becomes unusable until the process is killed and I am kicked back to my Display Manager.\r\n\r\n# Steps to reproduce\r\nIn your bar, create a new ``Image`` widget somewhere inside. Either provide a path to an image that does not exist, or do not provide one period.\r\n\r\n# Qtile version\r\nThis is the commit hash of the version I am running.\r\n6c4d0557124989d46ffb2bb24f4468db687fcdb2\r\n\r\n# Stack traces\r\nNo stack traces from xsession-errors, or the Qtile log are produced, however I have traced the error (through using the logger provided in the module's file) to the ``_configure`` method of the Image widget, and it seems to be coming the line: ``base._Widget._configure(self, qtile, bar)``\r\n\r\n# Configuration\r\nhttps://pastebin.com/qxBq6yPn\r\n\r\nIf there is any information I got wrong here, or some other bit of information I can provide that will help this issue get solved, I will try my best.\n", "before_files": [{"content": "# Copyright (c) 2013 dequis\n# Copyright (c) 2014 Sean Vig\n# Copyright (c) 2014 Adi Sieker\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.\nimport os\n\nfrom libqtile import bar\nfrom libqtile.images import Img\nfrom libqtile.log_utils import logger\nfrom libqtile.widget import base\n\n\nclass Image(base._Widget, base.MarginMixin):\n    \"\"\"Display a PNG image on the bar\"\"\"\n    orientations = base.ORIENTATION_BOTH\n    defaults = [\n        (\"scale\", True, \"Enable/Disable image scaling\"),\n        (\"rotate\", 0.0, \"rotate the image in degrees counter-clockwise\"),\n        (\"filename\", None, \"Image filename. Can contain '~'\"),\n    ]\n\n    def __init__(self, length=bar.CALCULATED, width=None, **config):\n        # 'width' was replaced by 'length' since the widget can be installed in\n        # vertical bars\n        if width is not None:\n            logger.warning('width kwarg or positional argument is '\n                           'deprecated. Please use length.')\n            length = width\n\n        base._Widget.__init__(self, length, **config)\n        self.add_defaults(Image.defaults)\n        self.add_defaults(base.MarginMixin.defaults)\n\n        # make the default 0 instead\n        self._variable_defaults[\"margin\"] = 0\n\n    def _configure(self, qtile, bar):\n        base._Widget._configure(self, qtile, bar)\n\n        if not self.filename:\n            raise ValueError(\"Filename not set!\")\n\n        self.filename = os.path.expanduser(self.filename)\n\n        if not os.path.exists(self.filename):\n            raise ValueError(\"File does not exist: {}\".format(self.filename))\n\n        img = Img.from_path(self.filename)\n        self.img = img\n        img.theta = self.rotate\n        if not self.scale:\n            return\n        if self.bar.horizontal:\n            new_height = self.bar.height - (self.margin_y * 2)\n            img.resize(height=new_height)\n        else:\n            new_width = self.bar.width - (self.margin_x * 2)\n            img.resize(width=new_width)\n\n    def draw(self):\n        self.drawer.clear(self.background or self.bar.background)\n        self.drawer.ctx.save()\n        self.drawer.ctx.translate(self.margin_x, self.margin_y)\n        self.drawer.ctx.set_source(self.img.pattern)\n        self.drawer.ctx.paint()\n        self.drawer.ctx.restore()\n\n        if self.bar.horizontal:\n            self.drawer.draw(offsetx=self.offset, width=self.width)\n        else:\n            self.drawer.draw(offsety=self.offset, height=self.width)\n\n    def calculate_length(self):\n        if self.bar.horizontal:\n            return self.img.width + (self.margin_x * 2)\n        else:\n            return self.img.height + (self.margin_y * 2)\n", "path": "libqtile/widget/image.py"}], "after_files": [{"content": "# Copyright (c) 2013 dequis\n# Copyright (c) 2014 Sean Vig\n# Copyright (c) 2014 Adi Sieker\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.\nimport os\n\nfrom libqtile import bar\nfrom libqtile.images import Img\nfrom libqtile.log_utils import logger\nfrom libqtile.widget import base\n\n\nclass Image(base._Widget, base.MarginMixin):\n    \"\"\"Display a PNG image on the bar\"\"\"\n    orientations = base.ORIENTATION_BOTH\n    defaults = [\n        (\"scale\", True, \"Enable/Disable image scaling\"),\n        (\"rotate\", 0.0, \"rotate the image in degrees counter-clockwise\"),\n        (\"filename\", None, \"Image filename. Can contain '~'\"),\n    ]\n\n    def __init__(self, length=bar.CALCULATED, width=None, **config):\n        # 'width' was replaced by 'length' since the widget can be installed in\n        # vertical bars\n        if width is not None:\n            logger.warning('width kwarg or positional argument is '\n                           'deprecated. Please use length.')\n            length = width\n\n        base._Widget.__init__(self, length, **config)\n        self.add_defaults(Image.defaults)\n        self.add_defaults(base.MarginMixin.defaults)\n\n        # make the default 0 instead\n        self._variable_defaults[\"margin\"] = 0\n\n    def _configure(self, qtile, bar):\n        base._Widget._configure(self, qtile, bar)\n        self.img = None\n\n        if not self.filename:\n            logger.warning(\"Image filename not set!\")\n            return\n\n        self.filename = os.path.expanduser(self.filename)\n\n        if not os.path.exists(self.filename):\n            logger.warning(\"Image does not exist: {}\".format(self.filename))\n            return\n\n        img = Img.from_path(self.filename)\n        self.img = img\n        img.theta = self.rotate\n        if not self.scale:\n            return\n        if self.bar.horizontal:\n            new_height = self.bar.height - (self.margin_y * 2)\n            img.resize(height=new_height)\n        else:\n            new_width = self.bar.width - (self.margin_x * 2)\n            img.resize(width=new_width)\n\n    def draw(self):\n        if self.img is None:\n            return\n\n        self.drawer.clear(self.background or self.bar.background)\n        self.drawer.ctx.save()\n        self.drawer.ctx.translate(self.margin_x, self.margin_y)\n        self.drawer.ctx.set_source(self.img.pattern)\n        self.drawer.ctx.paint()\n        self.drawer.ctx.restore()\n\n        if self.bar.horizontal:\n            self.drawer.draw(offsetx=self.offset, width=self.width)\n        else:\n            self.drawer.draw(offsety=self.offset, height=self.width)\n\n    def calculate_length(self):\n        if self.img is None:\n            return 0\n\n        if self.bar.horizontal:\n            return self.img.width + (self.margin_x * 2)\n        else:\n            return self.img.height + (self.margin_y * 2)\n", "path": "libqtile/widget/image.py"}]}