Repository: beetbox/beets

Issue:
Beets crashes on Python 3.8
### Problem

Beets crashes when running any command.

```sh
$ beet
Traceback (most recent call last):
  File "C:\Python38\Scripts\beet-script.py", line 11, in <module>
    load_entry_point('beets==1.4.8', 'console_scripts', 'beet')()
  File "C:\Python38\lib\site-packages\beets-1.4.8-py3.8.egg\beets\ui\__init__.py
", line 1266, in main
    _raw_main(args)
  File "C:\Python38\lib\site-packages\beets-1.4.8-py3.8.egg\beets\ui\__init__.py
", line 1249, in _raw_main
    subcommands, plugins, lib = _setup(options, lib)
  File "C:\Python38\lib\site-packages\beets-1.4.8-py3.8.egg\beets\ui\__init__.py
", line 1144, in _setup
    lib = _open_library(config)
  File "C:\Python38\lib\site-packages\beets-1.4.8-py3.8.egg\beets\ui\__init__.py
", line 1201, in _open_library
    get_path_formats(),
  File "C:\Python38\lib\site-packages\beets-1.4.8-py3.8.egg\beets\ui\__init__.py
", line 619, in get_path_formats
    path_formats.append((query, Template(view.as_str())))
  File "C:\Python38\lib\site-packages\beets-1.4.8-py3.8.egg\beets\util\functempl
ate.py", line 558, in __init__
    self.compiled = self.translate()
  File "C:\Python38\lib\site-packages\beets-1.4.8-py3.8.egg\beets\util\functempl
ate.py", line 591, in translate
    func = compile_func(
  File "C:\Python38\lib\site-packages\beets-1.4.8-py3.8.egg\beets\util\functempl
ate.py", line 147, in compile_func
    prog = compile(mod, '<generated>', 'exec')
TypeError: required field "type_ignores" missing from Module
```

### Setup

* OS: Windows 10 64-bit
* Python version: Python 3.8a3
* beets version: 1.4.8 (git-master)
* Turning off plugins made problem go away (yes/no): no

My configuration (output of `beet config`) is:

```yaml
empty
```

I've also compiled the wheel from git master obviously, I was having this issue from just installing it from pip normally, so I thought doing this manually would solve my issues, but it didn't. I don't really understand why this error occurs, but I imagine it has something to do with the dependencies of this project.


Discussion:
So it looks like the call signature of `ast.Module` [changed in 3.8 from `Module(stmt* body)` to `Module(stmt* body, type_ignore *type_ignores)`](https://github.com/python/cpython/pull/11645/files#diff-4d06871e531085389da207d32d01a005R6) which is annoying, although it looks like we should be able to change this line;

https://github.com/beetbox/beets/blob/728267d06c98b3696c1ba05b16b3f9b646f713e8/beets/util/functemplate.py#L144

To something like this;

```Python
if sys.version_info >= (3, 8):
    mod = ast.Module([func_def], [])
else:
    mod = ast.Module([func_def])
```

~I'm not really available to work on this right now, so hopefully this gives someone else a head-start.~ I'm going to go ahead and pick this up anyway :+1:

It might be worth enabling 3.8 on Travis too, although it is only officially being released in October this year.

Resolving patch:
diff --git a/beets/util/functemplate.py b/beets/util/functemplate.py
--- a/beets/util/functemplate.py
+++ b/beets/util/functemplate.py
@@ -141,7 +141,13 @@ def compile_func(arg_names, statements, name='_the_func', debug=False):
             decorator_list=[],
         )
 
-    mod = ast.Module([func_def])
+    # The ast.Module signature changed in 3.8 to accept a list of types to
+    # ignore.
+    if sys.version_info >= (3, 8):
+        mod = ast.Module([func_def], [])
+    else:
+        mod = ast.Module([func_def])
+
     ast.fix_missing_locations(mod)
 
     prog = compile(mod, '<generated>', 'exec')
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -154,6 +154,7 @@ def build_manpages():
         'Programming Language :: Python :: 3.5',
         'Programming Language :: Python :: 3.6',
         'Programming Language :: Python :: 3.7',
+        'Programming Language :: Python :: 3.8',
         'Programming Language :: Python :: Implementation :: CPython',
     ],
 )


Test patch: