prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Set version using importlib.metadata
  <!--
  Please do not ask general questions here! There are [community
  contact](https://github.com/qtile/qtile#community) options for that.
  
  If you are suggesting a new feature/enhancement please instead post it on the
  discussions board as an idea: https://github.com/qtile/qtile/discussions/categories/ideas
  -->
  
  # Issue description
  
  Currently, if setuptools is not installed on the system running qtile, it will run into issues upon start.
  An Arch user reported this downstream: https://bugs.archlinux.org/task/71804
  
  Apart from also guarding against `ModuleNotFoundError` I think it could be a great idea to [use importlib.metadata to provide qtile's version](https://docs.python.org/3.9/library/importlib.metadata.html?highlight=importlib%20metadata#distribution-versions) instead for newer python versions.
  <!--
  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".
  -->
  
  # Qtile version
  
  0.18.1
  
  # Stack traces
  
  Copied verbatim from the issue reported downstream:
  
  ```
  Traceback (most recent call last):
  File "/usr/lib/python3.9/site-packages/libqtile/scripts/main.py", line 9, in <module>
  import pkg_resources
  ModuleNotFoundError: No module named 'pkg_resources'
  
  During handling of the above exception, another exception occurred:
  
  Traceback (most recent call last):
  File "/usr/bin/qtile", line 33, in <module>
  sys.exit(load_entry_point('qtile==0.18.1.dev0+g8e7ecc0a.d20210719', 'console_scripts', 'qtile')())
  File "/usr/bin/qtile", line 25, in importlib_load_entry_point
  return next(matches).load()
  File "/usr/lib/python3.9/importlib/metadata.py", line 77, in load
  module = import_module(match.group('module'))
  File "/usr/lib/python3.9/importlib/__init__.py", line 127, in import_module
  return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 850, in exec_module
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "/usr/lib/python3.9/site-packages/libqtile/scripts/main.py", line 11, in <module>
  except (pkg_resources.DistributionNotFound, ImportError):
  NameError: name 'pkg_resources' is not defined
  ```
  
  # Configuration
  
  not important for this issue
  
  --- 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/main.py`
  Content:
  ```
  1 import argparse
  2 import logging
  3 import sys
  4 
  5 from libqtile.log_utils import init_log
  6 from libqtile.scripts import check, cmd_obj, migrate, run_cmd, shell, start, top
  7 
  8 try:
  9     import pkg_resources
  10     VERSION = pkg_resources.require("qtile")[0].version
  11 except (pkg_resources.DistributionNotFound, ImportError):
  12     VERSION = 'dev'
  13 
  14 
  15 def main():
  16     parent_parser = argparse.ArgumentParser(add_help=False)
  17     parent_parser.add_argument(
  18         '-l', '--log-level',
  19         default='WARNING',
  20         dest='log_level',
  21         type=str.upper,
  22         choices=('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'),
  23         help='Set qtile log level'
  24     )
  25 
  26     main_parser = argparse.ArgumentParser(
  27         prog='qtile',
  28         description='A full-featured, pure-Python tiling window manager.',
  29     )
  30     main_parser.add_argument(
  31         '-v', '--version',
  32         action='version',
  33         version=VERSION,
  34     )
  35 
  36     subparsers = main_parser.add_subparsers()
  37     start.add_subcommand(subparsers, [parent_parser])
  38     shell.add_subcommand(subparsers, [parent_parser])
  39     top.add_subcommand(subparsers, [parent_parser])
  40     run_cmd.add_subcommand(subparsers, [parent_parser])
  41     cmd_obj.add_subcommand(subparsers, [parent_parser])
  42     check.add_subcommand(subparsers, [parent_parser])
  43     migrate.add_subcommand(subparsers, [parent_parser])
  44 
  45     # `qtile help` should print help
  46     def print_help(options):
  47         main_parser.print_help()
  48     help_ = subparsers.add_parser("help", help="Print help information and exit")
  49     help_.set_defaults(func=print_help)
  50 
  51     options = main_parser.parse_args()
  52     try:
  53         log_level = getattr(logging, options.log_level)
  54         init_log(log_level=log_level, log_color=sys.stdout.isatty())
  55         options.func(options)
  56     except AttributeError:
  57         main_parser.print_usage()
  58         print("")
  59         print("Did you mean:")
  60         print(" ".join(sys.argv + ['start']))
  61         sys.exit(1)
  62 
  63 
  64 if __name__ == "__main__":
  65     main()
  66
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/libqtile/scripts/main.py b/libqtile/scripts/main.py
  --- a/libqtile/scripts/main.py
  +++ b/libqtile/scripts/main.py
  @@ -6,10 +6,16 @@
   from libqtile.scripts import check, cmd_obj, migrate, run_cmd, shell, start, top
   
   try:
  -    import pkg_resources
  -    VERSION = pkg_resources.require("qtile")[0].version
  -except (pkg_resources.DistributionNotFound, ImportError):
  -    VERSION = 'dev'
  +    # Python>3.7 can get the version from importlib
  +    from importlib.metadata import distribution
  +    VERSION = distribution("qtile").version
  +except ModuleNotFoundError:
  +    try:
  +        # pkg_resources is required for 3.7
  +        import pkg_resources
  +        VERSION = pkg_resources.require("qtile")[0].version
  +    except (pkg_resources.DistributionNotFound, ModuleNotFoundError):
  +        VERSION = 'dev'
   
   
   def main():
  
verification_info: {"golden_diff": "diff --git a/libqtile/scripts/main.py b/libqtile/scripts/main.py\n--- a/libqtile/scripts/main.py\n+++ b/libqtile/scripts/main.py\n@@ -6,10 +6,16 @@\n from libqtile.scripts import check, cmd_obj, migrate, run_cmd, shell, start, top\n \n try:\n-    import pkg_resources\n-    VERSION = pkg_resources.require(\"qtile\")[0].version\n-except (pkg_resources.DistributionNotFound, ImportError):\n-    VERSION = 'dev'\n+    # Python>3.7 can get the version from importlib\n+    from importlib.metadata import distribution\n+    VERSION = distribution(\"qtile\").version\n+except ModuleNotFoundError:\n+    try:\n+        # pkg_resources is required for 3.7\n+        import pkg_resources\n+        VERSION = pkg_resources.require(\"qtile\")[0].version\n+    except (pkg_resources.DistributionNotFound, ModuleNotFoundError):\n+        VERSION = 'dev'\n \n \n def main():\n", "issue": "Set version using importlib.metadata\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\nIf you are suggesting a new feature/enhancement please instead post it on the\r\ndiscussions board as an idea: https://github.com/qtile/qtile/discussions/categories/ideas\r\n-->\r\n\r\n# Issue description\r\n\r\nCurrently, if setuptools is not installed on the system running qtile, it will run into issues upon start.\r\nAn Arch user reported this downstream: https://bugs.archlinux.org/task/71804\r\n\r\nApart from also guarding against `ModuleNotFoundError` I think it could be a great idea to [use importlib.metadata to provide qtile's version](https://docs.python.org/3.9/library/importlib.metadata.html?highlight=importlib%20metadata#distribution-versions) instead for newer python versions.\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\n\r\n# Qtile version\r\n\r\n0.18.1\r\n\r\n# Stack traces\r\n\r\nCopied verbatim from the issue reported downstream:\r\n\r\n```\r\nTraceback (most recent call last):\r\nFile \"/usr/lib/python3.9/site-packages/libqtile/scripts/main.py\", line 9, in <module>\r\nimport pkg_resources\r\nModuleNotFoundError: No module named 'pkg_resources'\r\n\r\nDuring handling of the above exception, another exception occurred:\r\n\r\nTraceback (most recent call last):\r\nFile \"/usr/bin/qtile\", line 33, in <module>\r\nsys.exit(load_entry_point('qtile==0.18.1.dev0+g8e7ecc0a.d20210719', 'console_scripts', 'qtile')())\r\nFile \"/usr/bin/qtile\", line 25, in importlib_load_entry_point\r\nreturn next(matches).load()\r\nFile \"/usr/lib/python3.9/importlib/metadata.py\", line 77, in load\r\nmodule = import_module(match.group('module'))\r\nFile \"/usr/lib/python3.9/importlib/__init__.py\", line 127, in import_module\r\nreturn _bootstrap._gcd_import(name[level:], package, level)\r\nFile \"<frozen importlib._bootstrap>\", line 1030, in _gcd_import\r\nFile \"<frozen importlib._bootstrap>\", line 1007, in _find_and_load\r\nFile \"<frozen importlib._bootstrap>\", line 986, in _find_and_load_unlocked\r\nFile \"<frozen importlib._bootstrap>\", line 680, in _load_unlocked\r\nFile \"<frozen importlib._bootstrap_external>\", line 850, in exec_module\r\nFile \"<frozen importlib._bootstrap>\", line 228, in _call_with_frames_removed\r\nFile \"/usr/lib/python3.9/site-packages/libqtile/scripts/main.py\", line 11, in <module>\r\nexcept (pkg_resources.DistributionNotFound, ImportError):\r\nNameError: name 'pkg_resources' is not defined\r\n```\r\n\r\n# Configuration\r\n\r\nnot important for this issue\n", "before_files": [{"content": "import argparse\nimport logging\nimport sys\n\nfrom libqtile.log_utils import init_log\nfrom libqtile.scripts import check, cmd_obj, migrate, run_cmd, shell, start, top\n\ntry:\n    import pkg_resources\n    VERSION = pkg_resources.require(\"qtile\")[0].version\nexcept (pkg_resources.DistributionNotFound, ImportError):\n    VERSION = 'dev'\n\n\ndef main():\n    parent_parser = argparse.ArgumentParser(add_help=False)\n    parent_parser.add_argument(\n        '-l', '--log-level',\n        default='WARNING',\n        dest='log_level',\n        type=str.upper,\n        choices=('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'),\n        help='Set qtile log level'\n    )\n\n    main_parser = argparse.ArgumentParser(\n        prog='qtile',\n        description='A full-featured, pure-Python tiling window manager.',\n    )\n    main_parser.add_argument(\n        '-v', '--version',\n        action='version',\n        version=VERSION,\n    )\n\n    subparsers = main_parser.add_subparsers()\n    start.add_subcommand(subparsers, [parent_parser])\n    shell.add_subcommand(subparsers, [parent_parser])\n    top.add_subcommand(subparsers, [parent_parser])\n    run_cmd.add_subcommand(subparsers, [parent_parser])\n    cmd_obj.add_subcommand(subparsers, [parent_parser])\n    check.add_subcommand(subparsers, [parent_parser])\n    migrate.add_subcommand(subparsers, [parent_parser])\n\n    # `qtile help` should print help\n    def print_help(options):\n        main_parser.print_help()\n    help_ = subparsers.add_parser(\"help\", help=\"Print help information and exit\")\n    help_.set_defaults(func=print_help)\n\n    options = main_parser.parse_args()\n    try:\n        log_level = getattr(logging, options.log_level)\n        init_log(log_level=log_level, log_color=sys.stdout.isatty())\n        options.func(options)\n    except AttributeError:\n        main_parser.print_usage()\n        print(\"\")\n        print(\"Did you mean:\")\n        print(\" \".join(sys.argv + ['start']))\n        sys.exit(1)\n\n\nif __name__ == \"__main__\":\n    main()\n", "path": "libqtile/scripts/main.py"}], "after_files": [{"content": "import argparse\nimport logging\nimport sys\n\nfrom libqtile.log_utils import init_log\nfrom libqtile.scripts import check, cmd_obj, migrate, run_cmd, shell, start, top\n\ntry:\n    # Python>3.7 can get the version from importlib\n    from importlib.metadata import distribution\n    VERSION = distribution(\"qtile\").version\nexcept ModuleNotFoundError:\n    try:\n        # pkg_resources is required for 3.7\n        import pkg_resources\n        VERSION = pkg_resources.require(\"qtile\")[0].version\n    except (pkg_resources.DistributionNotFound, ModuleNotFoundError):\n        VERSION = 'dev'\n\n\ndef main():\n    parent_parser = argparse.ArgumentParser(add_help=False)\n    parent_parser.add_argument(\n        '-l', '--log-level',\n        default='WARNING',\n        dest='log_level',\n        type=str.upper,\n        choices=('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'),\n        help='Set qtile log level'\n    )\n\n    main_parser = argparse.ArgumentParser(\n        prog='qtile',\n        description='A full-featured, pure-Python tiling window manager.',\n    )\n    main_parser.add_argument(\n        '-v', '--version',\n        action='version',\n        version=VERSION,\n    )\n\n    subparsers = main_parser.add_subparsers()\n    start.add_subcommand(subparsers, [parent_parser])\n    shell.add_subcommand(subparsers, [parent_parser])\n    top.add_subcommand(subparsers, [parent_parser])\n    run_cmd.add_subcommand(subparsers, [parent_parser])\n    cmd_obj.add_subcommand(subparsers, [parent_parser])\n    check.add_subcommand(subparsers, [parent_parser])\n    migrate.add_subcommand(subparsers, [parent_parser])\n\n    # `qtile help` should print help\n    def print_help(options):\n        main_parser.print_help()\n    help_ = subparsers.add_parser(\"help\", help=\"Print help information and exit\")\n    help_.set_defaults(func=print_help)\n\n    options = main_parser.parse_args()\n    try:\n        log_level = getattr(logging, options.log_level)\n        init_log(log_level=log_level, log_color=sys.stdout.isatty())\n        options.func(options)\n    except AttributeError:\n        main_parser.print_usage()\n        print(\"\")\n        print(\"Did you mean:\")\n        print(\" \".join(sys.argv + ['start']))\n        sys.exit(1)\n\n\nif __name__ == \"__main__\":\n    main()\n", "path": "libqtile/scripts/main.py"}]}