Drop support for python 3.6

It is being EOLed next month (https://www.python.org/dev/peps/pep-0494/)
which is when I expect the next kitty release as well
This commit is contained in:
Kovid Goyal 2021-11-18 22:40:44 +05:30
parent bfdb09d29f
commit f0e8ab8f31
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
11 changed files with 40 additions and 66 deletions

View File

@ -20,15 +20,15 @@ jobs:
cc: [gcc, clang] cc: [gcc, clang]
include: include:
- python: a - python: a
pyver: 3.6 pyver: 3.7
sanitize: 0 sanitize: 0
- python: b - python: b
pyver: 3.7 pyver: 3.8
sanitize: 1 sanitize: 1
- python: c - python: c
pyver: 3.8 pyver: 3.9
sanitize: 1 sanitize: 1

View File

@ -1,5 +1,4 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net> # License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
import os import os

View File

@ -1,5 +1,4 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# vim:fileencoding=utf-8
# License: GPLv3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net> # License: GPLv3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
import subprocess import subprocess

View File

@ -1,5 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python
# vim:fileencoding=utf-8
# License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net> # License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>

View File

@ -1,5 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python
# vim:fileencoding=utf-8
# License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net> # License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
import string import string

View File

@ -1,5 +1,4 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net> # License: GPL v3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net>
import os import os
@ -255,7 +254,7 @@ def write_case(spec: Union[Tuple[int, ...], int], p: Callable[..., None]) -> Non
if isinstance(spec, tuple): if isinstance(spec, tuple):
p('\t\tcase 0x{:x} ... 0x{:x}:'.format(*spec)) p('\t\tcase 0x{:x} ... 0x{:x}:'.format(*spec))
else: else:
p('\t\tcase 0x{:x}:'.format(spec)) p(f'\t\tcase 0x{spec:x}:')
@contextmanager @contextmanager
@ -353,10 +352,10 @@ def classes_to_regex(classes: Iterable[str], exclude: str = '') -> Iterable[str]
def as_string(codepoint: int) -> str: def as_string(codepoint: int) -> str:
if codepoint < 256: if codepoint < 256:
return r'\x{:02x}'.format(codepoint) return fr'\x{codepoint:02x}'
if codepoint <= 0xffff: if codepoint <= 0xffff:
return r'\u{:04x}'.format(codepoint) return fr'\u{codepoint:04x}'
return r'\U{:08x}'.format(codepoint) return fr'\U{codepoint:08x}'
for spec in get_ranges(list(chars)): for spec in get_ranges(list(chars)):
if isinstance(spec, tuple): if isinstance(spec, tuple):

View File

@ -181,23 +181,11 @@ def resolve_custom_file(path: str) -> str:
def list_kitty_resources(package: str = 'kitty') -> Iterable[str]: def list_kitty_resources(package: str = 'kitty') -> Iterable[str]:
if sys.version_info < (3, 7):
from importlib_resources import files
def contents(package: str) -> Iterable[str]:
return (path.name for path in files(package).iterdir())
else:
from importlib.resources import contents from importlib.resources import contents
return contents(package) return contents(package)
def read_kitty_resource(name: str, package_name: str = 'kitty') -> bytes: def read_kitty_resource(name: str, package_name: str = 'kitty') -> bytes:
if sys.version_info < (3, 7):
from importlib_resources import files
def read_binary(package: str, resource: str) -> bytes:
return (files(package) / resource).read_bytes()
else:
from importlib.resources import read_binary from importlib.resources import read_binary
return read_binary(package_name, name) return read_binary(package_name, name)

View File

@ -5,16 +5,10 @@ import importlib
import os import os
import sys import sys
import unittest import unittest
from typing import Callable, Generator, NoReturn, Sequence, Set, Iterable from typing import Callable, Generator, NoReturn, Sequence, Set
if sys.version_info < (3, 7): from importlib.resources import contents
from importlib_resources import files
def contents(package: str) -> Iterable[str]:
return (path.name for path in files(package).iterdir())
else:
from importlib.resources import contents
def itertests(suite: unittest.TestSuite) -> Generator[unittest.TestCase, None, None]: def itertests(suite: unittest.TestSuite) -> Generator[unittest.TestCase, None, None]:

View File

@ -1,5 +1,4 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net> # License: GPL v3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net>
import argparse import argparse
@ -28,7 +27,7 @@ with open('kitty/constants.py') as f:
raw = f.read() raw = f.read()
nv = re.search(r'^version: Version\s+=\s+Version\((\d+), (\d+), (\d+)\)', raw, flags=re.MULTILINE) nv = re.search(r'^version: Version\s+=\s+Version\((\d+), (\d+), (\d+)\)', raw, flags=re.MULTILINE)
if nv is not None: if nv is not None:
version = '%s.%s.%s' % (nv.group(1), nv.group(2), nv.group(3)) version = f'{nv.group(1)}.{nv.group(2)}.{nv.group(3)}'
ap = re.search(r"^appname: str\s+=\s+'([^']+)'", raw, flags=re.MULTILINE) ap = re.search(r"^appname: str\s+=\s+'([^']+)'", raw, flags=re.MULTILINE)
if ap is not None: if ap is not None:
appname = ap.group(1) appname = ap.group(1)
@ -68,7 +67,7 @@ def run_build(args: Any) -> None:
def run_tag(args: Any) -> None: def run_tag(args: Any) -> None:
call('git push') call('git push')
call('git tag -s v{0} -m version-{0}'.format(version)) call('git tag -s v{0} -m version-{0}'.format(version))
call('git push origin v{0}'.format(version)) call(f'git push origin v{version}')
def run_man(args: Any) -> None: def run_man(args: Any) -> None:
@ -197,7 +196,7 @@ class ReadFileWithProgressReporting(io.FileIO): # {{{
# }}} # }}}
class Base(object): # {{{ class Base: # {{{
def info(self, *args: Any, **kwargs: Any) -> None: def info(self, *args: Any, **kwargs: Any) -> None:
print(*args, **kwargs) print(*args, **kwargs)
@ -293,7 +292,7 @@ class GitHub(Base): # {{{
release['tag_name']) release['tag_name'])
for asset in release['assets']: for asset in release['assets']:
r = self.requests.delete( r = self.requests.delete(
self.API + 'repos/%s/%s/releases/assets/%s' % ( self.API + 'repos/{}/{}/releases/assets/{}'.format(
self.username, self.reponame, asset['id'])) self.username, self.reponame, asset['id']))
if r.status_code != 204: if r.status_code != 204:
self.fail( self.fail(
@ -303,7 +302,7 @@ class GitHub(Base): # {{{
def do_upload(self, url: str, path: str, desc: str, fname: str) -> requests.Response: def do_upload(self, url: str, path: str, desc: str, fname: str) -> requests.Response:
mime_type = mimetypes.guess_type(fname)[0] or 'application/octet-stream' mime_type = mimetypes.guess_type(fname)[0] or 'application/octet-stream'
self.info('Uploading to GitHub: %s (%s)' % (fname, mime_type)) self.info(f'Uploading to GitHub: {fname} ({mime_type})')
with ReadFileWithProgressReporting(path) as f: with ReadFileWithProgressReporting(path) as f:
return self.requests.post( return self.requests.post(
url, url,
@ -325,7 +324,7 @@ class GitHub(Base): # {{{
return bool(error_code == 'already_exists') return bool(error_code == 'already_exists')
def existing_assets(self, release_id: str) -> Dict[str, str]: def existing_assets(self, release_id: str) -> Dict[str, str]:
url = self.API + 'repos/%s/%s/releases/%s/assets' % ( url = self.API + 'repos/{}/{}/releases/{}/assets'.format(
self.username, self.reponame, release_id) self.username, self.reponame, release_id)
r = self.requests.get(url) r = self.requests.get(url)
if r.status_code != 200: if r.status_code != 200:
@ -341,7 +340,7 @@ class GitHub(Base): # {{{
return dict(r.json()) return dict(r.json())
if self.is_nightly: if self.is_nightly:
raise SystemExit('No existing nightly release found on GitHub') raise SystemExit('No existing nightly release found on GitHub')
url = self.API + 'repos/%s/%s/releases' % (self.username, self.reponame) url = self.API + f'repos/{self.username}/{self.reponame}/releases'
r = self.requests.post( r = self.requests.post(
url, url,
data=json.dumps({ data=json.dumps({
@ -413,7 +412,7 @@ def current_branch() -> str:
def require_git_master(branch: str = 'master') -> None: def require_git_master(branch: str = 'master') -> None:
if current_branch() != branch: if current_branch() != branch:
raise SystemExit('You must be in the {} git branch'.format(branch)) raise SystemExit(f'You must be in the {branch} git branch')
def safe_read(path: str) -> str: def safe_read(path: str) -> str:
@ -490,7 +489,7 @@ def main() -> None:
del actions[1:] del actions[1:]
else: else:
try: try:
ans = input('Publish version \033[91m{}\033[m (y/n): '.format(version)) ans = input(f'Publish version \033[91m{version}\033[m (y/n): ')
except KeyboardInterrupt: except KeyboardInterrupt:
ans = 'n' ans = 'n'
if ans.lower() != 'y': if ans.lower() != 'y':

View File

@ -1,5 +1,4 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net> # License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
import argparse import argparse
@ -27,8 +26,8 @@ from typing import (
from glfw import glfw from glfw import glfw
from glfw.glfw import Command, CompileKey from glfw.glfw import Command, CompileKey
if sys.version_info[:2] < (3, 6): if sys.version_info[:2] < (3, 7):
raise SystemExit('kitty requires python >= 3.6') raise SystemExit('kitty requires python >= 3.7')
base = os.path.dirname(os.path.abspath(__file__)) base = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, base) sys.path.insert(0, base)
del sys.path[0] del sys.path[0]
@ -104,7 +103,7 @@ def pkg_config(pkg: str, *args: str) -> List[str]:
) )
) )
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
raise SystemExit('The package {} was not found on your system'.format(error(pkg))) raise SystemExit(f'The package {error(pkg)} was not found on your system')
def pkg_version(package: str) -> Tuple[int, int]: def pkg_version(package: str) -> Tuple[int, int]:
@ -118,7 +117,7 @@ def pkg_version(package: str) -> Tuple[int, int]:
def at_least_version(package: str, major: int, minor: int = 0) -> None: def at_least_version(package: str, major: int, minor: int = 0) -> None:
q = '{}.{}'.format(major, minor) q = f'{major}.{minor}'
if subprocess.run([PKGCONFIG, package, '--atleast-version=' + q] if subprocess.run([PKGCONFIG, package, '--atleast-version=' + q]
).returncode != 0: ).returncode != 0:
qmajor = qminor = 0 qmajor = qminor = 0
@ -185,10 +184,10 @@ def get_python_flags(cflags: List[str]) -> List[str]:
if fw: if fw:
for var in 'data include stdlib'.split(): for var in 'data include stdlib'.split():
val = sysconfig.get_path(var) val = sysconfig.get_path(var)
if val and '/{}.framework'.format(fw) in val: if val and f'/{fw}.framework' in val:
fdir = val[:val.index('/{}.framework'.format(fw))] fdir = val[:val.index(f'/{fw}.framework')]
if os.path.isdir( if os.path.isdir(
os.path.join(fdir, '{}.framework'.format(fw)) os.path.join(fdir, f'{fw}.framework')
): ):
framework_dir = fdir framework_dir = fdir
break break
@ -406,8 +405,8 @@ def kitty_env() -> Env:
# We add 4000 to the primary version because vim turns on SGR mouse mode # We add 4000 to the primary version because vim turns on SGR mouse mode
# automatically if this version is high enough # automatically if this version is high enough
cppflags = ans.cppflags cppflags = ans.cppflags
cppflags.append('-DPRIMARY_VERSION={}'.format(version[0] + 4000)) cppflags.append(f'-DPRIMARY_VERSION={version[0] + 4000}')
cppflags.append('-DSECONDARY_VERSION={}'.format(version[1])) cppflags.append(f'-DSECONDARY_VERSION={version[1]}')
cppflags.append('-DXT_VERSION="{}"'.format('.'.join(map(str, version)))) cppflags.append('-DXT_VERSION="{}"'.format('.'.join(map(str, version))))
at_least_version('harfbuzz', 1, 5) at_least_version('harfbuzz', 1, 5)
cflags.extend(pkg_config('libpng', '--cflags-only-I')) cflags.extend(pkg_config('libpng', '--cflags-only-I'))
@ -484,7 +483,7 @@ def get_vcs_rev_defines(env: Env, src: str) -> List[str]:
with open(os.path.join(gitloc, 'refs/heads/master')) as f: with open(os.path.join(gitloc, 'refs/heads/master')) as f:
rev = f.read() rev = f.read()
ans.append('KITTY_VCS_REV="{}"'.format(rev.strip())) ans.append(f'KITTY_VCS_REV="{rev.strip()}"')
return ans return ans
@ -573,9 +572,9 @@ def parallel_run(items: List[Command]) -> None:
if verbose: if verbose:
print(' '.join(compile_cmd.cmd)) print(' '.join(compile_cmd.cmd))
elif isatty: elif isatty:
print('\r\x1b[K[{}/{}] {}'.format(num, total, compile_cmd.desc), end='') print(f'\r\x1b[K[{num}/{total}] {compile_cmd.desc}', end='')
else: else:
print('[{}/{}] {}'.format(num, total, compile_cmd.desc), flush=True) print(f'[{num}/{total}] {compile_cmd.desc}', flush=True)
printed = True printed = True
w = subprocess.Popen(compile_cmd.cmd, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT) w = subprocess.Popen(compile_cmd.cmd, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
workers[w.pid] = compile_cmd, w workers[w.pid] = compile_cmd, w
@ -696,12 +695,12 @@ def compile_c_extension(
cmd = kenv.cc + ['-MMD'] + cppflags + kenv.cflags cmd = kenv.cc + ['-MMD'] + cppflags + kenv.cflags
cmd += ['-c', src] + ['-o', dest] cmd += ['-c', src] + ['-o', dest]
key = CompileKey(original_src, os.path.basename(dest)) key = CompileKey(original_src, os.path.basename(dest))
desc = 'Compiling {} ...'.format(emphasis(desc_prefix + src)) desc = f'Compiling {emphasis(desc_prefix + src)} ...'
compilation_database.add_command(desc, cmd, partial(newer, dest, *dependecies_for(src, dest, headers)), key=key, keyfile=src) compilation_database.add_command(desc, cmd, partial(newer, dest, *dependecies_for(src, dest, headers)), key=key, keyfile=src)
dest = os.path.join(build_dir, module + '.so') dest = os.path.join(build_dir, module + '.so')
real_dest = module + '.so' real_dest = module + '.so'
os.makedirs(os.path.dirname(dest), exist_ok=True) os.makedirs(os.path.dirname(dest), exist_ok=True)
desc = 'Linking {} ...'.format(emphasis(desc_prefix + module)) desc = f'Linking {emphasis(desc_prefix + module)} ...'
# Old versions of clang don't like -pthread being passed to the linker # Old versions of clang don't like -pthread being passed to the linker
# Don't treat linker warnings as errors (linker generates spurious # Don't treat linker warnings as errors (linker generates spurious
# warnings on some old systems) # warnings on some old systems)
@ -755,7 +754,7 @@ def compile_glfw(compilation_database: CompilationDatabase) -> None:
continue continue
compile_c_extension( compile_c_extension(
genv, 'kitty/glfw-' + module, compilation_database, genv, 'kitty/glfw-' + module, compilation_database,
sources, all_headers, desc_prefix='[{}] '.format(module)) sources, all_headers, desc_prefix=f'[{module}] ')
def kittens_env() -> Env: def kittens_env() -> Env:
@ -784,7 +783,7 @@ def compile_kittens(compilation_database: CompilationDatabase) -> None:
) -> Tuple[str, List[str], List[str], str, Sequence[str], Sequence[str]]: ) -> Tuple[str, List[str], List[str], str, Sequence[str], Sequence[str]]:
sources = list(filter(filter_sources, list(extra_sources) + list_files(os.path.join('kittens', kitten, '*.c')))) sources = list(filter(filter_sources, list(extra_sources) + list_files(os.path.join('kittens', kitten, '*.c'))))
headers = list_files(os.path.join('kittens', kitten, '*.h')) + list(extra_headers) headers = list_files(os.path.join('kittens', kitten, '*.h')) + list(extra_headers)
return kitten, sources, headers, 'kittens/{}/{}'.format(kitten, output), includes, libraries return kitten, sources, headers, f'kittens/{kitten}/{output}', includes, libraries
for kitten, sources, all_headers, dest, includes, libraries in ( for kitten, sources, all_headers, dest, includes, libraries in (
files('unicode_input', 'unicode_names'), files('unicode_input', 'unicode_names'),
@ -848,8 +847,8 @@ def build_launcher(args: Options, launcher_dir: str = '.', bundle_type: str = 's
cflags.append('-O3') cflags.append('-O3')
if bundle_type.endswith('-freeze'): if bundle_type.endswith('-freeze'):
cppflags.append('-DFOR_BUNDLE') cppflags.append('-DFOR_BUNDLE')
cppflags.append('-DPYVER="{}"'.format(sysconfig.get_python_version())) cppflags.append(f'-DPYVER="{sysconfig.get_python_version()}"')
cppflags.append('-DKITTY_LIB_DIR_NAME="{}"'.format(args.libdir_name)) cppflags.append(f'-DKITTY_LIB_DIR_NAME="{args.libdir_name}"')
elif bundle_type == 'source': elif bundle_type == 'source':
cppflags.append('-DFROM_SOURCE') cppflags.append('-DFROM_SOURCE')
if bundle_type.startswith('macos-'): if bundle_type.startswith('macos-'):
@ -859,8 +858,8 @@ def build_launcher(args: Options, launcher_dir: str = '.', bundle_type: str = 's
elif bundle_type == 'source': elif bundle_type == 'source':
klp = os.path.relpath('.', launcher_dir) klp = os.path.relpath('.', launcher_dir)
else: else:
raise SystemExit('Unknown bundle type: {}'.format(bundle_type)) raise SystemExit(f'Unknown bundle type: {bundle_type}')
cppflags.append('-DKITTY_LIB_PATH="{}"'.format(klp)) cppflags.append(f'-DKITTY_LIB_PATH="{klp}"')
pylib = get_python_flags(cflags) pylib = get_python_flags(cflags)
cppflags += shlex.split(os.environ.get('CPPFLAGS', '')) cppflags += shlex.split(os.environ.get('CPPFLAGS', ''))
cflags += shlex.split(os.environ.get('CFLAGS', '')) cflags += shlex.split(os.environ.get('CFLAGS', ''))

View File

@ -1,5 +1,4 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net> # License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
import importlib import importlib