More typing work

Also move notification_activated into a standalone function which will
hopefully fix #2410
This commit is contained in:
Kovid Goyal 2020-03-06 07:07:18 +05:30
parent 1e998b6a3f
commit f729985346
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 86 additions and 62 deletions

View File

@ -38,9 +38,16 @@ from .utils import (
log_error, open_url, parse_address_spec, remove_socket_file, safe_print,
set_primary_selection, single_instance, startup_notification_handler
)
from .window import Window
def listen_on(spec):
def notification_activated(identifier: str) -> None:
if identifier == 'new-version':
from .update_check import notification_activated
notification_activated()
def listen_on(spec: str) -> int:
import socket
family, address, socket_path = parse_address_spec(spec)
s = socket.socket(family)
@ -50,8 +57,8 @@ def listen_on(spec):
return s.fileno()
def data_for_at(w, arg, add_wrap_markers=False):
def as_text(**kw):
def data_for_at(w: Window, arg: str, add_wrap_markers: bool = False) -> str:
def as_text(**kw) -> str:
kw['add_wrap_markers'] = add_wrap_markers
return w.as_text(**kw)
@ -143,7 +150,7 @@ class Boss:
change_os_window_state(args.start_as)
if is_macos:
from .fast_data_types import cocoa_set_notification_activated_callback
cocoa_set_notification_activated_callback(self.notification_activated)
cocoa_set_notification_activated_callback(notification_activated)
def add_os_window(self, startup_session=None, os_window_id=None, wclass=None, wname=None, opts_for_size=None, startup_id=None):
if os_window_id is None:
@ -1141,11 +1148,6 @@ class Boss:
except Exception as e:
log_error('Failed to process update check data {!r}, with error: {}'.format(raw, e))
def notification_activated(self, identifier):
if identifier == 'new-version':
from .update_check import notification_activated
notification_activated()
def dbus_notification_callback(self, activated, *args):
from .notify import dbus_notification_created, dbus_notification_activated
if activated:

128
setup.py
View File

@ -15,10 +15,11 @@ import subprocess
import sys
import sysconfig
import time
from functools import partial
from collections import namedtuple
from contextlib import suppress
from functools import partial
from pathlib import Path
from typing import Callable, Dict, List, NamedTuple, Optional, Sequence, Tuple
if sys.version_info[:2] < (3, 6):
raise SystemExit('kitty requires python >= 3.6')
@ -42,9 +43,34 @@ version = tuple(
)
_plat = sys.platform.lower()
is_macos = 'darwin' in _plat
env = None
class Env:
def __init__(
self, cc: str = '', cppflags: List[str] = [], cflags: List[str] = [], ldflags: List[str] = [],
ldpaths: Optional[List[str]] = None, ccver: Optional[Tuple[int, int]] = None
):
self.cc, self.cppflags, self.cflags, self.ldflags, self.ldpaths = cc, cppflags, cflags, ldflags, [] if ldpaths is None else ldpaths
self.ccver = ccver
def copy(self):
return Env(self.cc, list(self.cppflags), list(self.cflags), list(self.ldflags), list(self.ldpaths), self.ccver)
env = Env()
PKGCONFIG = os.environ.get('PKGCONFIG_EXE', 'pkg-config')
CompileKey = namedtuple('CompileKey', 'src dest')
class Command(NamedTuple):
desc: str
cmd: Sequence[str]
is_newer_func: Callable[[], bool]
on_success: Callable[[], None]
key: Optional[CompileKey]
keyfile: Optional[str]
def emphasis(text):
@ -78,13 +104,15 @@ def at_least_version(package, major, minor=0):
q = '{}.{}'.format(major, minor)
if subprocess.run([PKGCONFIG, package, '--atleast-version=' + q]
).returncode != 0:
qmajor = qminor = 0
try:
ver = subprocess.check_output([PKGCONFIG, package, '--modversion']
).decode('utf-8').strip()
qmajor, qminor = map(int, re.match(r'(\d+).(\d+)', ver).groups())
m = re.match(r'(\d+).(\d+)', ver)
if m is not None:
qmajor, qminor = map(int, m.groups())
except Exception:
ver = 'not found'
qmajor = qminor = 0
if qmajor < major or (qmajor == major and qminor < minor):
raise SystemExit(
'{} >= {}.{} is required, found version: {}'.format(
@ -93,7 +121,7 @@ def at_least_version(package, major, minor=0):
)
def cc_version():
def cc_version() -> Tuple[str, Tuple[int, int]]:
if 'CC' in os.environ:
cc = os.environ['CC']
else:
@ -107,9 +135,9 @@ def cc_version():
else:
cc = 'cc'
raw = subprocess.check_output([cc, '-dumpversion']).decode('utf-8')
ver = raw.split('.')[:2]
ver_ = raw.split('.')[:2]
try:
ver = tuple(map(int, ver))
ver = int(ver_[0]), int(ver_[1])
except Exception:
ver = (0, 0)
return cc, ver
@ -125,9 +153,9 @@ def get_python_include_paths():
def get_python_flags(cflags):
cflags.extend('-I' + x for x in get_python_include_paths())
libs = []
libs += sysconfig.get_config_var('LIBS').split()
libs += sysconfig.get_config_var('SYSLIBS').split()
libs: List[str] = []
libs += (sysconfig.get_config_var('LIBS') or '').split()
libs += (sysconfig.get_config_var('SYSLIBS') or '').split()
fw = sysconfig.get_config_var('PYTHONFRAMEWORK')
if fw:
for var in 'data include stdlib'.split():
@ -141,15 +169,17 @@ def get_python_flags(cflags):
break
else:
raise SystemExit('Failed to find Python framework')
libs.append(
os.path.join(framework_dir, sysconfig.get_config_var('LDLIBRARY'))
)
ldlib = sysconfig.get_config_var('LDLIBRARY')
if ldlib:
libs.append(os.path.join(framework_dir, ldlib))
else:
libs += ['-L' + sysconfig.get_config_var('LIBDIR')]
libs += [
'-lpython' + sysconfig.get_config_var('VERSION') + sys.abiflags
]
libs += sysconfig.get_config_var('LINKFORSHARED').split()
ldlib = sysconfig.get_config_var('LIBDIR')
if ldlib:
libs += ['-L' + ldlib]
ldlib = sysconfig.get_config_var('VERSION')
if ldlib:
libs += ['-lpython' + ldlib + sys.abiflags]
libs += (sysconfig.get_config_var('LINKFORSHARED') or '').split()
return libs
@ -180,16 +210,6 @@ def first_successful_compile(cc, *cflags, src=None):
return ''
class Env:
def __init__(self, cc, cppflags, cflags, ldflags, ldpaths=None, ccver=None):
self.cc, self.cppflags, self.cflags, self.ldflags, self.ldpaths = cc, cppflags, cflags, ldflags, [] if ldpaths is None else ldpaths
self.ccver = ccver
def copy(self):
return Env(self.cc, list(self.cppflags), list(self.cflags), list(self.ldflags), list(self.ldpaths), self.ccver)
def init_env(
debug=False, sanitize=False, native_optimizations=True, profile=False,
extra_logging=()
@ -209,13 +229,13 @@ def init_env(
fortify_source = '-D_FORTIFY_SOURCE=2'
optimize = df if debug or sanitize else '-O3'
sanitize_args = get_sanitize_args(cc, ccver) if sanitize else set()
cppflags = os.environ.get(
cppflags_ = os.environ.get(
'OVERRIDE_CPPFLAGS', '-D{}DEBUG'.format('' if debug else 'N'),
)
cppflags = shlex.split(cppflags)
cppflags = shlex.split(cppflags_)
for el in extra_logging:
cppflags.append('-DDEBUG_{}'.format(el.upper().replace('-', '_')))
cflags = os.environ.get(
cflags_ = os.environ.get(
'OVERRIDE_CFLAGS', (
'-Wextra {} -Wno-missing-field-initializers -Wall -Wstrict-prototypes -std=c11'
' -pedantic-errors -Werror {} {} -fwrapv {} {} -pipe {} -fvisibility=hidden {}'
@ -229,21 +249,22 @@ def init_env(
fortify_source
)
)
cflags = shlex.split(cflags) + shlex.split(
sysconfig.get_config_var('CCSHARED')
cflags = shlex.split(cflags_) + shlex.split(
sysconfig.get_config_var('CCSHARED') or ''
)
ldflags = os.environ.get(
ldflags_ = os.environ.get(
'OVERRIDE_LDFLAGS',
'-Wall ' + ' '.join(sanitize_args) + ('' if debug else ' -O3')
)
ldflags = shlex.split(ldflags)
ldflags = shlex.split(ldflags_)
ldflags.append('-shared')
cppflags += shlex.split(os.environ.get('CPPFLAGS', ''))
cflags += shlex.split(os.environ.get('CFLAGS', ''))
ldflags += shlex.split(os.environ.get('LDFLAGS', ''))
if not debug and not sanitize:
# See https://github.com/google/sanitizers/issues/647
cflags.append('-flto'), ldflags.append('-flto')
cflags.append('-flto')
ldflags.append('-flto')
if profile:
cppflags.append('-DWITH_PROFILER')
@ -373,11 +394,11 @@ def dependecies_for(src, obj, all_headers):
def parallel_run(items):
try:
num_workers = max(2, os.cpu_count())
num_workers = max(2, os.cpu_count() or 1)
except Exception:
num_workers = 2
items = list(reversed(items))
workers = {}
workers: Dict[int, Tuple[Optional[Command], Optional[subprocess.Popen]]] = {}
failed = None
num, total = 0, len(items)
@ -387,7 +408,9 @@ def parallel_run(items):
return
pid, s = os.wait()
compile_cmd, w = workers.pop(pid, (None, None))
if compile_cmd is not None and ((s & 0xff) != 0 or ((s >> 8) & 0xff) != 0):
if compile_cmd is None:
return
if ((s & 0xff) != 0 or ((s >> 8) & 0xff) != 0):
if failed is None:
failed = compile_cmd
elif compile_cmd.on_success is not None:
@ -415,10 +438,6 @@ def parallel_run(items):
run_tool(failed.cmd)
CompileKey = namedtuple('CompileKey', 'src dest')
Command = namedtuple('Command', 'desc cmd is_newer_func on_success key keyfile')
class CompilationDatabase:
def __init__(self, incremental):
@ -499,10 +518,12 @@ def compile_c_extension(kenv, module, compilation_database, sources, headers, de
cppflags = kenv.cppflags[:]
is_special = src in SPECIAL_SOURCES
if is_special:
src, defines = SPECIAL_SOURCES[src]
if callable(defines):
defines = defines()
cppflags.extend(map(define, defines))
src, defines_ = SPECIAL_SOURCES[src]
if callable(defines_):
defines = defines_()
cppflags.extend(map(define, defines))
else:
cppflags.extend(map(define, defines_))
cmd = [kenv.cc, '-MMD'] + cppflags + kenv.cflags
cmd += ['-c', src] + ['-o', dest]
@ -697,7 +718,7 @@ def compile_python(base_path):
import compileall
import py_compile
try:
num_workers = max(1, os.cpu_count())
num_workers = max(1, os.cpu_count() or 1)
except Exception:
num_workers = 1
for root, dirs, files in os.walk(base_path):
@ -705,10 +726,10 @@ def compile_python(base_path):
if f.rpartition('.')[-1] in ('pyc', 'pyo'):
os.remove(os.path.join(root, f))
for optimize in (0, 1, 2):
kwargs = dict(ddir='', force=True, optimize=optimize, quiet=1, workers=num_workers)
if hasattr(py_compile, 'PycInvalidationMode'):
kwargs['invalidation_mode'] = py_compile.PycInvalidationMode.UNCHECKED_HASH
compileall.compile_dir(base_path, **kwargs)
compileall.compile_dir(
base_path, ddir='', force=True, optimize=optimize, quiet=1,
workers=num_workers, invalidation_mode=py_compile.PycInvalidationMode.UNCHECKED_HASH
)
def create_linux_bundle_gunk(ddir, libdir_name):
@ -802,7 +823,8 @@ def create_minimal_macos_bundle(args, where):
shutil.rmtree(where)
bin_dir = os.path.join(where, 'kitty.app/Contents/MacOS')
resources_dir = os.path.join(where, 'kitty.app/Contents/Resources')
os.makedirs(resources_dir), os.makedirs(bin_dir)
os.makedirs(resources_dir)
os.makedirs(bin_dir)
with open(os.path.join(where, 'kitty.app/Contents/Info.plist'), 'wb') as f:
f.write(macos_info_plist())
build_launcher(args, bin_dir)