Privatize all attributes which aren't needed from the outside.

This commit is contained in:
Florian Bruhin 2014-09-24 22:17:53 +02:00
parent 75da8a7f1b
commit 62e55499eb
23 changed files with 430 additions and 424 deletions

View File

@ -43,15 +43,15 @@ class DownloadItem(QObject):
estimate the remaining time.
Attributes:
reply: The QNetworkReply associated with this download.
bytes_done: How many bytes there are already downloaded.
bytes_total: The total count of bytes.
None if the total is unknown.
speed: The current download speed, in bytes per second.
fileobj: The file object to download the file to.
filename: The filename of the download.
is_cancelled: Whether the download was cancelled.
speed_avg: A rolling average of speeds.
_bytes_done: How many bytes there are already downloaded.
_bytes_total: The total count of bytes.
None if the total is unknown.
_speed: The current download speed, in bytes per second.
_fileobj: The file object to download the file to.
_filename: The filename of the download.
_is_cancelled: Whether the download was cancelled.
_speed_avg: A rolling average of speeds.
_reply: The QNetworkReply associated with this download.
_last_done: The count of bytes which where downloaded when calculating
the speed the last time.
@ -77,18 +77,18 @@ class DownloadItem(QObject):
reply: The QNetworkReply to download.
"""
super().__init__(parent)
self.reply = reply
self.bytes_total = None
self.speed = 0
self._reply = reply
self._bytes_total = None
self._speed = 0
self.basename = '???'
samples = int(self.SPEED_AVG_WINDOW *
(1000 / self.SPEED_REFRESH_INTERVAL))
self.speed_avg = collections.deque(maxlen=samples)
self.fileobj = None
self.filename = None
self.is_cancelled = False
self._speed_avg = collections.deque(maxlen=samples)
self._fileobj = None
self._filename = None
self._is_cancelled = False
self._do_delayed_write = False
self.bytes_done = 0
self._bytes_done = 0
self._last_done = 0
reply.setReadBufferSize(16 * 1024 * 1024)
reply.downloadProgress.connect(self.on_download_progress)
@ -115,11 +115,11 @@ class DownloadItem(QObject):
Example: foo.pdf [699.2kB/s|0.34|16%|4.253/25.124]
"""
speed = utils.format_size(self.speed, suffix='B/s')
down = utils.format_size(self.bytes_done, suffix='B')
speed = utils.format_size(self._speed, suffix='B/s')
down = utils.format_size(self._bytes_done, suffix='B')
perc = self._percentage()
remaining = self._remaining_time()
if all(e is None for e in (perc, remaining, self.bytes_total)):
if all(e is None for e in (perc, remaining, self._bytes_total)):
return ('{name} [{speed:>10}|{down}]'.format(
name=self.basename, speed=speed, down=down))
if perc is None:
@ -130,7 +130,7 @@ class DownloadItem(QObject):
remaining = '?'
else:
remaining = utils.format_seconds(remaining)
total = utils.format_size(self.bytes_total, suffix='B')
total = utils.format_size(self._bytes_total, suffix='B')
return ('{name} [{speed:>10}|{remaining:>5}|{perc:>2}%|'
'{down}/{total}]'.format(name=self.basename, speed=speed,
remaining=remaining, perc=perc,
@ -138,36 +138,36 @@ class DownloadItem(QObject):
def _die(self, msg):
"""Abort the download and emit an error."""
self.reply.downloadProgress.disconnect()
self.reply.finished.disconnect()
self.reply.error.disconnect()
self.reply.readyRead.disconnect()
self.bytes_done = self.bytes_total
self._reply.downloadProgress.disconnect()
self._reply.finished.disconnect()
self._reply.error.disconnect()
self._reply.readyRead.disconnect()
self._bytes_done = self._bytes_total
self.timer.stop()
self.error.emit(msg)
self.reply.abort()
self.reply.deleteLater()
if self.fileobj is not None:
self._reply.abort()
self._reply.deleteLater()
if self._fileobj is not None:
try:
self.fileobj.close()
self._fileobj.close()
except OSError as e:
self.error.emit(e.strerror)
self.finished.emit()
def _percentage(self):
"""The current download percentage, or None if unknown."""
if self.bytes_total == 0 or self.bytes_total is None:
if self._bytes_total == 0 or self._bytes_total is None:
return None
else:
return 100 * self.bytes_done / self.bytes_total
return 100 * self._bytes_done / self._bytes_total
def _remaining_time(self):
"""The remaining download time in seconds, or None."""
if self.bytes_total is None or not self.speed_avg:
if self._bytes_total is None or not self._speed_avg:
# No average yet or we don't know the total size.
return None
remaining_bytes = self.bytes_total - self.bytes_done
avg = sum(self.speed_avg) / len(self.speed_avg)
remaining_bytes = self._bytes_total - self._bytes_done
avg = sum(self._speed_avg) / len(self._speed_avg)
if avg == 0:
# Download stalled
return None
@ -189,13 +189,13 @@ class DownloadItem(QObject):
"""Cancel the download."""
log.downloads.debug("cancelled")
self.cancelled.emit()
self.is_cancelled = True
self.reply.abort()
self.reply.deleteLater()
if self.fileobj is not None:
self.fileobj.close()
if self.filename is not None and os.path.exists(self.filename):
os.remove(self.filename)
self._is_cancelled = True
self._reply.abort()
self._reply.deleteLater()
if self._fileobj is not None:
self._fileobj.close()
if self._filename is not None and os.path.exists(self._filename):
os.remove(self._filename)
self.finished.emit()
def set_filename(self, filename):
@ -205,19 +205,19 @@ class DownloadItem(QObject):
filename: The full filename to save the download to.
None: special value to stop the download.
"""
if self.filename is not None:
if self._filename is not None:
raise ValueError("Filename was already set! filename: {}, "
"existing: {}".format(filename, self.filename))
"existing: {}".format(filename, self._filename))
filename = os.path.expanduser(filename)
if os.path.isabs(filename) and os.path.isdir(filename):
# We got an absolute directory from the user, so we save it under
# the default filename in that directory.
self.filename = os.path.join(filename, self.basename)
self._filename = os.path.join(filename, self.basename)
elif os.path.isabs(filename):
# We got an absolute filename from the user, so we save it under
# that filename.
self.filename = filename
self.basename = os.path.basename(self.filename)
self._filename = filename
self.basename = os.path.basename(self._filename)
else:
# We only got a filename (without directory) from the user, so we
# save it under that filename in the default directory.
@ -225,11 +225,11 @@ class DownloadItem(QObject):
if download_dir is None:
download_dir = utils.get_standard_dir(
QStandardPaths.DownloadLocation)
self.filename = os.path.join(download_dir, filename)
self._filename = os.path.join(download_dir, filename)
self.basename = filename
log.downloads.debug("Setting filename to {}".format(filename))
try:
self.fileobj = open(self.filename, 'wb')
self._fileobj = open(self._filename, 'wb')
if self._do_delayed_write:
# Downloading to the buffer in RAM has already finished so we
# write out the data and clean up now.
@ -246,10 +246,10 @@ class DownloadItem(QObject):
"""Write buffered data to disk and finish the QNetworkReply."""
log.downloads.debug("Doing delayed write...")
self._do_delayed_write = False
self.fileobj.write(self.reply.readAll())
self.fileobj.close()
self.reply.close()
self.reply.deleteLater()
self._fileobj.write(self._reply.readAll())
self._fileobj.close()
self._reply.close()
self._reply.deleteLater()
self.finished.emit()
log.downloads.debug("Download finished")
@ -263,8 +263,8 @@ class DownloadItem(QObject):
"""
if bytes_total == -1:
bytes_total = None
self.bytes_done = bytes_done
self.bytes_total = bytes_total
self._bytes_done = bytes_done
self._bytes_total = bytes_total
self.data_changed.emit()
@pyqtSlot()
@ -275,12 +275,12 @@ class DownloadItem(QObject):
doesn't mean the download (i.e. writing data to the disk) is finished
as well. Therefore, we can't close() the QNetworkReply in here yet.
"""
self.bytes_done = self.bytes_total
self._bytes_done = self._bytes_total
self.timer.stop()
if self.is_cancelled:
if self._is_cancelled:
return
log.downloads.debug("Reply finished, fileobj {}".format(self.fileobj))
if self.fileobj is None:
log.downloads.debug("Reply finished, fileobj {}".format(self._fileobj))
if self._fileobj is None:
# We'll handle emptying the buffer and cleaning up as soon as the
# filename is set.
self._do_delayed_write = True
@ -292,11 +292,11 @@ class DownloadItem(QObject):
@pyqtSlot()
def on_ready_read(self):
"""Read available data and save file when ready to read."""
if self.fileobj is None:
if self._fileobj is None:
# No filename has been set yet, so we don't empty the buffer.
return
try:
self.fileobj.write(self.reply.readAll())
self._fileobj.write(self._reply.readAll())
except OSError as e:
self._die(e.strerror)
@ -306,15 +306,15 @@ class DownloadItem(QObject):
if code == QNetworkReply.OperationCanceledError:
return
else:
self.error.emit(self.reply.errorString())
self.error.emit(self._reply.errorString())
@pyqtSlot()
def update_speed(self):
"""Recalculate the current download speed."""
delta = self.bytes_done - self._last_done
self.speed = delta * 1000 / self.SPEED_REFRESH_INTERVAL
self.speed_avg.append(self.speed)
self._last_done = self.bytes_done
delta = self._bytes_done - self._last_done
self._speed = delta * 1000 / self.SPEED_REFRESH_INTERVAL
self._speed_avg.append(self._speed)
self._last_done = self._bytes_done
self.data_changed.emit()

View File

@ -91,16 +91,16 @@ class register: # pylint: disable=invalid-name
much cleaner to implement.
Attributes:
instance: The instance to be used as "self", as a dotted string.
name: The name (as string) or names (as list) of the command.
split: Whether to split the arguments.
hide: Whether to hide the command or not.
completion: Which completion to use for arguments, as a list of
strings.
modes/not_modes: List of modes to use/not use.
needs_js: If javascript is needed for this command.
debug: Whether this is a debugging command (only shown with --debug).
ignore_args: Whether to ignore the arguments of the function.
_instance: The instance to be used as "self", as a dotted string.
_name: The name (as string) or names (as list) of the command.
_split: Whether to split the arguments.
_hide: Whether to hide the command or not.
_completion: Which completion to use for arguments, as a list of
strings.
_modes/_not_modes: List of modes to use/not use.
_needs_js: If javascript is needed for this command.
_debug: Whether this is a debugging command (only shown with --debug).
_ignore_args: Whether to ignore the arguments of the function.
"""
def __init__(self, instance=None, name=None, split=True, hide=False,
@ -116,16 +116,16 @@ class register: # pylint: disable=invalid-name
# pylint: disable=too-many-arguments
if modes is not None and not_modes is not None:
raise ValueError("Only modes or not_modes can be given!")
self.name = name
self.split = split
self.hide = hide
self.instance = instance
self.completion = completion
self.modes = modes
self.not_modes = not_modes
self.needs_js = needs_js
self.debug = debug
self.ignore_args = ignore_args
self._name = name
self._split = split
self._hide = hide
self._instance = instance
self._completion = completion
self._modes = modes
self._not_modes = not_modes
self._needs_js = needs_js
self._debug = debug
self._ignore_args = ignore_args
if modes is not None:
for m in modes:
if not isinstance(m, usertypes.KeyMode):
@ -150,12 +150,12 @@ class register: # pylint: disable=invalid-name
Return:
A list of names, with the main name being the first item.
"""
if self.name is None:
if self._name is None:
return [func.__name__.lower().replace('_', '-')]
elif isinstance(self.name, str):
return [self.name]
elif isinstance(self._name, str):
return [self._name]
else:
return self.name
return self._name
def __call__(self, func):
"""Register the command before running the function.
@ -178,10 +178,11 @@ class register: # pylint: disable=invalid-name
if name in cmd_dict:
raise ValueError("{} is already registered!".format(name))
cmd = command.Command(
name=names[0], split=self.split, hide=self.hide,
instance=self.instance, completion=self.completion,
modes=self.modes, not_modes=self.not_modes, needs_js=self.needs_js,
is_debug=self.debug, ignore_args=self.ignore_args, handler=func)
name=names[0], split=self._split, hide=self._hide,
instance=self._instance, completion=self._completion,
modes=self._modes, not_modes=self._not_modes,
needs_js=self._needs_js, is_debug=self._debug,
ignore_args=self._ignore_args, handler=func)
for name in names:
cmd_dict[name] = cmd
aliases += names[1:]

View File

@ -37,17 +37,18 @@ class Command:
name: The main name of the command.
split: Whether to split the arguments.
hide: Whether to hide the arguments or not.
count: Whether the command supports a count, or not.
desc: The description of the command.
instance: How to get to the "self" argument of the handler.
A dotted string as viewed from app.py, or None.
handler: The handler function to call.
completion: Completions to use for arguments, as a list of strings.
needs_js: Whether the command needs javascript enabled
debug: Whether this is a debugging command (only shown with --debug).
parser: The ArgumentParser to use to parse this command.
type_conv: A mapping of conversion functions for arguments.
name_conv: A mapping of argument names to parameter names.
_type_conv: A mapping of conversion functions for arguments.
_name_conv: A mapping of argument names to parameter names.
_needs_js: Whether the command needs javascript enabled
_modes: The modes the command can be executed in.
_not_modes: The modes the command can not be executed in.
_count: Whether the command supports a count, or not.
_instance: The object to bind 'self' to.
Class attributes:
AnnotationInfo: Named tuple for info from an annotation.
@ -66,11 +67,11 @@ class Command:
self.name = name
self.split = split
self.hide = hide
self.instance = instance
self._instance = instance
self.completion = completion
self.modes = modes
self.not_modes = not_modes
self.needs_js = needs_js
self._modes = modes
self._not_modes = not_modes
self._needs_js = needs_js
self.debug = is_debug
self.ignore_args = ignore_args
self.handler = handler
@ -84,13 +85,13 @@ class Command:
self._check_func()
self.opt_args = collections.OrderedDict()
self.namespace = None
self.count = None
self._count = None
self.pos_args = []
has_count, desc, type_conv, name_conv = self._inspect_func()
self.has_count = has_count
self.desc = desc
self.type_conv = type_conv
self.name_conv = name_conv
self._type_conv = type_conv
self._name_conv = name_conv
def _check_prerequisites(self):
"""Check if the command is permitted to run currently.
@ -99,17 +100,17 @@ class Command:
PrerequisitesError if the command can't be called currently.
"""
curmode = objreg.get('mode-manager').mode()
if self.modes is not None and curmode not in self.modes:
mode_names = '/'.join(mode.name for mode in self.modes)
if self._modes is not None and curmode not in self._modes:
mode_names = '/'.join(mode.name for mode in self._modes)
raise cmdexc.PrerequisitesError(
"{}: This command is only allowed in {} mode.".format(
self.name, mode_names))
elif self.not_modes is not None and curmode in self.not_modes:
mode_names = '/'.join(mode.name for mode in self.not_modes)
elif self._not_modes is not None and curmode in self._not_modes:
mode_names = '/'.join(mode.name for mode in self._not_modes)
raise cmdexc.PrerequisitesError(
"{}: This command is not allowed in {} mode.".format(
self.name, mode_names))
if self.needs_js and not QWebSettings.globalSettings().testAttribute(
if self._needs_js and not QWebSettings.globalSettings().testAttribute(
QWebSettings.JavascriptEnabled):
raise cmdexc.PrerequisitesError(
"{}: This command needs javascript enabled.".format(self.name))
@ -117,10 +118,10 @@ class Command:
def _check_func(self):
"""Make sure the function parameters don't violate any rules."""
signature = inspect.signature(self.handler)
if 'self' in signature.parameters and self.instance is None:
if 'self' in signature.parameters and self._instance is None:
raise TypeError("{} is a class method, but instance was not "
"given!".format(self.name[0]))
elif 'self' not in signature.parameters and self.instance is not None:
elif 'self' not in signature.parameters and self._instance is not None:
raise TypeError("{} is not a class method, but instance was "
"given!".format(self.name[0]))
elif inspect.getfullargspec(self.handler).varkw is not None:
@ -299,7 +300,7 @@ class Command:
args: The positional argument list. Gets modified directly.
"""
assert param.kind == inspect.Parameter.POSITIONAL_OR_KEYWORD
obj = objreg.get(self.instance)
obj = objreg.get(self._instance)
args.append(obj)
def _get_count_arg(self, param, args, kwargs):
@ -314,27 +315,27 @@ class Command:
raise TypeError("{}: count argument given with a command which "
"does not support count!".format(self.name))
if param.kind == inspect.Parameter.POSITIONAL_OR_KEYWORD:
if self.count is not None:
args.append(self.count)
if self._count is not None:
args.append(self._count)
else:
args.append(param.default)
elif param.kind == inspect.Parameter.KEYWORD_ONLY:
if self.count is not None:
kwargs['count'] = self.count
if self._count is not None:
kwargs['count'] = self._count
else:
raise TypeError("{}: invalid parameter type {} for argument "
"'count'!".format(self.name, param.kind))
def _get_param_name_and_value(self, param):
"""Get the converted name and value for an inspect.Parameter."""
name = self.name_conv.get(param.name, param.name)
name = self._name_conv.get(param.name, param.name)
value = getattr(self.namespace, name)
if param.name in self.type_conv:
if param.name in self._type_conv:
# We convert enum types after getting the values from
# argparse, because argparse's choices argument is
# processed after type conversation, which is not what we
# want.
value = self.type_conv[param.name](value)
value = self._type_conv[param.name](value)
return name, value
def _get_call_args(self):
@ -349,13 +350,13 @@ class Command:
signature = inspect.signature(self.handler)
if self.ignore_args:
if self.instance is not None:
if self._instance is not None:
param = list(signature.parameters.values())[0]
self._get_self_arg(param, args)
return args, kwargs
for i, param in enumerate(signature.parameters.values()):
if i == 0 and self.instance is not None:
if i == 0 and self._instance is not None:
# Special case for 'self'.
self._get_self_arg(param, args)
continue
@ -401,7 +402,7 @@ class Command:
log.commands.debug("argparser exited with status {}: {}".format(
e.status, e))
return
self.count = count
self._count = count
posargs, kwargs = self._get_call_args()
self._check_prerequisites()
log.commands.debug('Calling {}'.format(

View File

@ -51,7 +51,7 @@ class _BlockingFIFOReader(QObject):
was requested.
Attributes:
filepath: The filename of the FIFO to read.
_filepath: The filename of the FIFO to read.
fifo: The file object which is being read.
Signals:
@ -65,7 +65,7 @@ class _BlockingFIFOReader(QObject):
def __init__(self, filepath, parent=None):
super().__init__(parent)
self.filepath = filepath
self._filepath = filepath
self.fifo = None
def read(self):
@ -74,7 +74,7 @@ class _BlockingFIFOReader(QObject):
# See http://www.outflux.net/blog/archives/2008/03/09/using-select-on-a-fifo/
# We also use os.open and os.fdopen rather than built-in open so we can
# add O_NONBLOCK.
fd = os.open(self.filepath, os.O_RDWR |
fd = os.open(self._filepath, os.O_RDWR |
os.O_NONBLOCK, # pylint: disable=no-member
encoding='utf-8')
self.fifo = os.fdopen(fd, 'r')
@ -96,8 +96,8 @@ class _BaseUserscriptRunner(QObject):
"""Common part between the Windows and the POSIX userscript runners.
Attributes:
filepath: The path of the file/FIFO which is being read.
proc: The QProcess which is being executed.
_filepath: The path of the file/FIFO which is being read.
_proc: The QProcess which is being executed.
Class attributes:
PROCESS_MESSAGES: A mapping of QProcess::ProcessError members to
@ -124,8 +124,8 @@ class _BaseUserscriptRunner(QObject):
def __init__(self, parent=None):
super().__init__(parent)
self.filepath = None
self.proc = None
self._filepath = None
self._proc = None
def _run_process(self, cmd, *args, env):
"""Start the given command via QProcess.
@ -135,27 +135,27 @@ class _BaseUserscriptRunner(QObject):
*args: The arguments to hand to the command
env: A dictionary of environment variables to add.
"""
self.proc = QProcess(self)
self._proc = QProcess(self)
procenv = QProcessEnvironment.systemEnvironment()
procenv.insert('QUTE_FIFO', self.filepath)
procenv.insert('QUTE_FIFO', self._filepath)
if env is not None:
for k, v in env.items():
procenv.insert(k, v)
self.proc.setProcessEnvironment(procenv)
self.proc.error.connect(self.on_proc_error)
self.proc.finished.connect(self.on_proc_finished)
self.proc.start(cmd, args)
self._proc.setProcessEnvironment(procenv)
self._proc.error.connect(self.on_proc_error)
self._proc.finished.connect(self.on_proc_finished)
self._proc.start(cmd, args)
def _cleanup(self):
"""Clean up the temporary file."""
try:
os.remove(self.filepath)
os.remove(self._filepath)
except PermissionError as e:
# NOTE: Do not replace this with "raise CommandError" as it's
# executed async.
message.error("Failed to delete tempfile... ({})".format(e))
self.filepath = None
self.proc = None
self._filepath = None
self._proc = None
def run(self, cmd, *args, env=None):
"""Run the userscript given.
@ -192,14 +192,14 @@ class _POSIXUserscriptRunner(_BaseUserscriptRunner):
executed immediately when they arrive in the FIFO.
Attributes:
reader: The _BlockingFIFOReader instance.
thread: The QThread where reader runs.
_reader: The _BlockingFIFOReader instance.
_thread: The QThread where reader runs.
"""
def __init__(self, parent=None):
super().__init__(parent)
self.reader = None
self.thread = None
self._reader = None
self._thread = None
def run(self, cmd, *args, env=None):
rundir = utils.get_standard_dir(QStandardPaths.RuntimeLocation)
@ -208,43 +208,43 @@ class _POSIXUserscriptRunner(_BaseUserscriptRunner):
# directory and place the FIFO there, which sucks. Since os.kfifo will
# raise an exception anyways when the path doesn't exist, it shouldn't
# be a big issue.
self.filepath = tempfile.mktemp(prefix='userscript-', dir=rundir)
os.mkfifo(self.filepath) # pylint: disable=no-member
self._filepath = tempfile.mktemp(prefix='userscript-', dir=rundir)
os.mkfifo(self._filepath) # pylint: disable=no-member
self.reader = _BlockingFIFOReader(self.filepath)
self.thread = QThread(self)
self.reader.moveToThread(self.thread)
self.reader.got_line.connect(self.got_cmd)
self.thread.started.connect(self.reader.read)
self.reader.finished.connect(self.on_reader_finished)
self.thread.finished.connect(self.on_thread_finished)
self._reader = _BlockingFIFOReader(self._filepath)
self._thread = QThread(self)
self._reader.moveToThread(self._thread)
self._reader.got_line.connect(self.got_cmd)
self._thread.started.connect(self._reader.read)
self._reader.finished.connect(self.on_reader_finished)
self._thread.finished.connect(self.on_thread_finished)
self._run_process(cmd, *args, env=env)
self.thread.start()
self._thread.start()
def on_proc_finished(self):
"""Interrupt the reader when the process finished."""
log.procs.debug("proc finished")
self.thread.requestInterruption()
self._thread.requestInterruption()
def on_proc_error(self, error):
"""Interrupt the reader when the process had an error."""
super().on_proc_error(error)
self.thread.requestInterruption()
self._thread.requestInterruption()
def on_reader_finished(self):
"""Quit the thread and clean up when the reader finished."""
log.procs.debug("reader finished")
self.thread.quit()
self.reader.fifo.close()
self.reader.deleteLater()
self._thread.quit()
self._reader.fifo.close()
self._reader.deleteLater()
super()._cleanup()
self.finished.emit()
def on_thread_finished(self):
"""Clean up the QThread object when the thread finished."""
log.procs.debug("thread finished")
self.thread.deleteLater()
self._thread.deleteLater()
class _WindowsUserscriptRunner(_BaseUserscriptRunner):
@ -262,13 +262,13 @@ class _WindowsUserscriptRunner(_BaseUserscriptRunner):
def __init__(self, parent=None):
super().__init__(parent)
self.oshandle = None
self._oshandle = None
def _cleanup(self):
"""Clean up temporary files after the userscript finished."""
os.close(self.oshandle)
os.close(self._oshandle)
super()._cleanup()
self.oshandle = None
self._oshandle = None
def on_proc_finished(self):
"""Read back the commands when the process finished.
@ -277,7 +277,7 @@ class _WindowsUserscriptRunner(_BaseUserscriptRunner):
got_cmd: Emitted for every command in the file.
"""
log.procs.debug("proc finished")
with open(self.filepath, 'r', encoding='utf-8') as f:
with open(self._filepath, 'r', encoding='utf-8') as f:
for line in f:
self.got_cmd.emit(line.rstrip())
self._cleanup()
@ -290,7 +290,7 @@ class _WindowsUserscriptRunner(_BaseUserscriptRunner):
self.finished.emit()
def run(self, cmd, *args, env=None):
self.oshandle, self.filepath = tempfile.mkstemp(text=True)
self._oshandle, self._filepath = tempfile.mkstemp(text=True)
self._run_process(cmd, *args, env=env)

View File

@ -86,7 +86,7 @@ class BaseType:
"""A type used for a setting value.
Attributes:
none_ok: Whether to convert to None for an empty string.
_none_ok: Whether to convert to None for an empty string.
Class attributes:
valid_values: Possible values if they can be expressed as a fixed
@ -98,7 +98,7 @@ class BaseType:
valid_values = None
def __init__(self, none_ok=False):
self.none_ok = none_ok
self._none_ok = none_ok
def transform(self, value):
"""Transform the setting value.
@ -132,7 +132,7 @@ class BaseType:
NotImplementedError if self.valid_values is not defined and this
method should be overridden.
"""
if not value and self.none_ok:
if not value and self._none_ok:
return
if self.valid_values is not None:
if value not in self.valid_values:
@ -196,7 +196,7 @@ class String(BaseType):
def validate(self, value):
if not value:
if self.none_ok:
if self._none_ok:
return
else:
raise ValidationError(value, "may not be empty!")
@ -224,7 +224,7 @@ class List(BaseType):
def validate(self, value):
vals = self.transform(value)
if None in vals:
if self.none_ok:
if self._none_ok:
pass
else:
raise ValidationError(value, "items may not be empty!")
@ -252,7 +252,7 @@ class Bool(BaseType):
def validate(self, value):
if not value:
if self.none_ok:
if self._none_ok:
return
else:
raise ValidationError(value, "may not be empty!")
@ -290,7 +290,7 @@ class Int(BaseType):
def validate(self, value):
if not value:
if self.none_ok:
if self._none_ok:
return
else:
raise ValidationError(value, "may not be empty!")
@ -321,7 +321,7 @@ class IntList(List):
vals = self.transform(value)
except ValueError:
raise ValidationError(value, "must be a list of integers!")
if None in vals and not self.none_ok:
if None in vals and not self._none_ok:
raise ValidationError(value, "items may not be empty!")
@ -352,7 +352,7 @@ class Float(BaseType):
def validate(self, value):
if not value:
if self.none_ok:
if self._none_ok:
return
else:
raise ValidationError(value, "may not be empty!")
@ -395,7 +395,7 @@ class Perc(BaseType):
def validate(self, value):
if not value:
if self.none_ok:
if self._none_ok:
return
else:
raise ValidationError(value, "may not be empty")
@ -442,7 +442,7 @@ class PercList(List):
try:
for val in vals:
if val is None:
if self.none_ok:
if self._none_ok:
continue
else:
raise ValidationError(value, "items may not be empty!")
@ -481,7 +481,7 @@ class PercOrInt(BaseType):
def validate(self, value):
if not value:
if self.none_ok:
if self._none_ok:
return
else:
raise ValidationError(value, "may not be empty!")
@ -517,7 +517,7 @@ class Command(BaseType):
def validate(self, value):
if not value:
if self.none_ok:
if self._none_ok:
return
else:
raise ValidationError(value, "may not be empty!")
@ -541,7 +541,7 @@ class ColorSystem(BaseType):
def validate(self, value):
if not value:
if self.none_ok:
if self._none_ok:
return
else:
raise ValidationError(value, "may not be empty!")
@ -567,7 +567,7 @@ class QtColor(BaseType):
def validate(self, value):
if not value:
if self.none_ok:
if self._none_ok:
return
else:
raise ValidationError(value, "may not be empty!")
@ -591,7 +591,7 @@ class CssColor(BaseType):
def validate(self, value):
if not value:
if self.none_ok:
if self._none_ok:
return
else:
raise ValidationError(value, "may not be empty!")
@ -626,7 +626,7 @@ class QssColor(CssColor):
def validate(self, value):
if not value:
if self.none_ok:
if self._none_ok:
return
else:
raise ValidationError(value, "may not be empty!")
@ -662,7 +662,7 @@ class Font(BaseType):
def validate(self, value):
if not value:
if self.none_ok:
if self._none_ok:
return
else:
raise ValidationError(value, "may not be empty!")
@ -729,7 +729,7 @@ class Regex(BaseType):
def validate(self, value):
if not value:
if self.none_ok:
if self._none_ok:
return
else:
raise ValidationError(value, "may not be empty!")
@ -766,7 +766,7 @@ class RegexList(List):
except sre_constants.error as e:
raise ValidationError(value, "must be a list valid regexes - " +
str(e))
if not self.none_ok and None in vals:
if not self._none_ok and None in vals:
raise ValidationError(value, "items may not be empty!")
@ -778,7 +778,7 @@ class File(BaseType):
def validate(self, value):
if not value:
if self.none_ok:
if self._none_ok:
return
else:
raise ValidationError(value, "may not be empty!")
@ -802,7 +802,7 @@ class Directory(BaseType):
def validate(self, value):
if not value:
if self.none_ok:
if self._none_ok:
return
else:
raise ValidationError(value, "may not be empty!")
@ -903,7 +903,7 @@ class WebKitBytesList(List):
vals = super().transform(value)
for val in vals:
self.bytestype.validate(val)
if None in vals and not self.none_ok:
if None in vals and not self._none_ok:
raise ValidationError(value, "items may not be empty!")
if self.length is not None and len(vals) != self.length:
raise ValidationError(value, "exactly {} values need to be "
@ -926,7 +926,7 @@ class ShellCommand(BaseType):
def validate(self, value):
if not value:
if self.none_ok:
if self._none_ok:
return
else:
raise ValidationError(value, "may not be empty!")
@ -975,7 +975,7 @@ class Proxy(BaseType):
def validate(self, value):
if not value:
if self.none_ok:
if self._none_ok:
return
else:
raise ValidationError(value, "may not be empty!")
@ -1022,7 +1022,7 @@ class SearchEngineName(BaseType):
def validate(self, value):
if not value:
if self.none_ok:
if self._none_ok:
return
else:
raise ValidationError(value, "may not be empty!")
@ -1034,7 +1034,7 @@ class SearchEngineUrl(BaseType):
def validate(self, value):
if not value:
if self.none_ok:
if self._none_ok:
return
else:
raise ValidationError(value, "may not be empty!")
@ -1054,7 +1054,7 @@ class Encoding(BaseType):
def validate(self, value):
if not value:
if self.none_ok:
if self._none_ok:
return
else:
raise ValidationError(value, "may not be empty!")
@ -1075,7 +1075,7 @@ class UserStyleSheet(File):
def validate(self, value):
if not value:
if self.none_ok:
if self._none_ok:
return
else:
raise ValidationError(value, "may not be empty!")
@ -1117,7 +1117,7 @@ class AutoSearch(BaseType):
def validate(self, value):
if not value:
if self.none_ok:
if self._none_ok:
return
else:
raise ValidationError(value, "may not be empty!")

View File

@ -53,8 +53,8 @@ class BaseKeyParser(QObject):
Attributes:
bindings: Bound keybindings
special_bindings: Bound special bindings (<Foo>).
warn_on_keychains: Whether a warning should be logged when binding
keychains in a section which does not support them.
_warn_on_keychains: Whether a warning should be logged when binding
keychains in a section which does not support them.
_keystring: The currently entered key sequence
_timer: Timer for delayed execution.
_modename: The name of the input mode associated with this keyparser.
@ -83,7 +83,7 @@ class BaseKeyParser(QObject):
supports_count = supports_chains
self._supports_count = supports_count
self._supports_chains = supports_chains
self.warn_on_keychains = True
self._warn_on_keychains = True
self.bindings = {}
self.special_bindings = {}
@ -330,7 +330,7 @@ class BaseKeyParser(QObject):
self.special_bindings[keystr] = cmd
elif self._supports_chains:
self.bindings[key] = cmd
elif self.warn_on_keychains:
elif self._warn_on_keychains:
log.keyboard.warning(
"Ignoring keychain '{}' in mode '{}' because "
"keychains are not supported there.".format(key, modename))

View File

@ -29,17 +29,17 @@ class CommandKeyParser(BaseKeyParser):
"""KeyChainParser for command bindings.
Attributes:
commandrunner: CommandRunner instance.
_commandrunner: CommandRunner instance.
"""
def __init__(self, parent=None, supports_count=None,
supports_chains=False):
super().__init__(parent, supports_count, supports_chains)
self.commandrunner = runners.CommandRunner()
self._commandrunner = runners.CommandRunner()
def execute(self, cmdstr, _keytype, count=None):
try:
self.commandrunner.run(cmdstr, count)
self._commandrunner.run(cmdstr, count)
except (cmdexc.CommandMetaError, cmdexc.CommandError) as e:
message.error(e, immediately=True)
@ -66,10 +66,10 @@ class PassthroughKeyParser(CommandKeyParser):
"""
super().__init__(parent, supports_chains=False)
self.log = False
self.warn_on_keychains = warn
self._warn_on_keychains = warn
self.read_config(mode)
self._mode = mode
def __repr__(self):
return '<{} mode={}, warn={})'.format(
self.__class__.__name__, self._mode, self.warn_on_keychains)
self.__class__.__name__, self._mode, self._warn_on_keychains)

View File

@ -19,6 +19,8 @@
"""Tests for qutebrowser.utils.editor."""
# pylint: disable=protected-access
import os
import os.path
import unittest
@ -59,7 +61,7 @@ class ArgTests(unittest.TestCase):
editor.config = stubs.ConfigStub(
{'general': {'editor': ['bin'], 'editor-encoding': 'utf-8'}})
self.editor.edit("")
self.editor.proc.start.assert_called_with("bin", [])
self.editor._proc.start.assert_called_with("bin", [])
def test_start_args(self):
"""Test starting editor with static arguments."""
@ -67,7 +69,7 @@ class ArgTests(unittest.TestCase):
{'general': {'editor': ['bin', 'foo', 'bar'],
'editor-encoding': 'utf-8'}})
self.editor.edit("")
self.editor.proc.start.assert_called_with("bin", ["foo", "bar"])
self.editor._proc.start.assert_called_with("bin", ["foo", "bar"])
def test_placeholder(self):
"""Test starting editor with placeholder argument."""
@ -75,9 +77,9 @@ class ArgTests(unittest.TestCase):
{'general': {'editor': ['bin', 'foo', '{}', 'bar'],
'editor-encoding': 'utf-8'}})
self.editor.edit("")
filename = self.editor.filename
self.editor.proc.start.assert_called_with("bin",
["foo", filename, "bar"])
filename = self.editor._filename
self.editor._proc.start.assert_called_with("bin",
["foo", filename, "bar"])
def test_in_arg_placeholder(self):
"""Test starting editor with placeholder argument inside argument."""
@ -85,7 +87,7 @@ class ArgTests(unittest.TestCase):
{'general': {'editor': ['bin', 'foo{}bar'],
'editor-encoding': 'utf-8'}})
self.editor.edit("")
self.editor.proc.start.assert_called_with("bin", ["foo{}bar"])
self.editor._proc.start.assert_called_with("bin", ["foo{}bar"])
def tearDown(self):
self.editor._cleanup() # pylint: disable=protected-access
@ -107,7 +109,7 @@ class FileHandlingTests(unittest.TestCase):
def test_file_handling_closed_ok(self):
"""Test file handling when closing with an exitstatus == 0."""
self.editor.edit("")
filename = self.editor.filename
filename = self.editor._filename
self.assertTrue(os.path.exists(filename))
self.editor.on_proc_closed(0, QProcess.NormalExit)
self.assertFalse(os.path.exists(filename))
@ -115,7 +117,7 @@ class FileHandlingTests(unittest.TestCase):
def test_file_handling_closed_error(self):
"""Test file handling when closing with an exitstatus != 0."""
self.editor.edit("")
filename = self.editor.filename
filename = self.editor._filename
self.assertTrue(os.path.exists(filename))
self.editor.on_proc_closed(1, QProcess.NormalExit)
self.assertFalse(os.path.exists(filename))
@ -123,7 +125,7 @@ class FileHandlingTests(unittest.TestCase):
def test_file_handling_closed_crash(self):
"""Test file handling when closing with a crash."""
self.editor.edit("")
filename = self.editor.filename
filename = self.editor._filename
self.assertTrue(os.path.exists(filename))
self.editor.on_proc_error(QProcess.Crashed)
self.editor.on_proc_closed(0, QProcess.CrashExit)
@ -150,7 +152,7 @@ class TextModifyTests(unittest.TestCase):
Args:
text: The text to write to the file.
"""
filename = self.editor.filename
filename = self.editor._filename
with open(filename, 'w', encoding='utf-8') as f:
f.write(text)
@ -160,7 +162,7 @@ class TextModifyTests(unittest.TestCase):
Return:
The text which was read.
"""
filename = self.editor.filename
filename = self.editor._filename
with open(filename, 'r', encoding='utf-8') as f:
data = f.read()
return data

View File

@ -171,18 +171,18 @@ class RAMHandlerTests(BaseTest):
"""Test handler with exactly as much records as it can hold."""
self.logger.debug("One")
self.logger.debug("Two")
self.assertEqual(len(self.handler.data), 2)
self.assertEqual(self.handler.data[0].msg, "One")
self.assertEqual(self.handler.data[1].msg, "Two")
self.assertEqual(len(self.handler._data), 2)
self.assertEqual(self.handler._data[0].msg, "One")
self.assertEqual(self.handler._data[1].msg, "Two")
def test_overflow(self):
"""Test handler with more records as it can hold."""
self.logger.debug("One")
self.logger.debug("Two")
self.logger.debug("Three")
self.assertEqual(len(self.handler.data), 2)
self.assertEqual(self.handler.data[0].msg, "Two")
self.assertEqual(self.handler.data[1].msg, "Three")
self.assertEqual(len(self.handler._data), 2)
self.assertEqual(self.handler._data[0].msg, "Two")
self.assertEqual(self.handler._data[1].msg, "Three")
def test_dump_log(self):
"""Test dump_log()."""

View File

@ -19,6 +19,8 @@
"""Tests for qutebrowser.utils.readline."""
# pylint: disable=protected-access
import inspect
import unittest
from unittest import mock
@ -105,7 +107,7 @@ class ReadlineBridgeTest(unittest.TestCase):
self._set_selected_text("delete test")
self.bridge.rl_unix_line_discard()
self.qle.home.assert_called_with(True)
self.assertEqual(self.bridge.deleted[self.qle], "delete test")
self.assertEqual(self.bridge._deleted[self.qle], "delete test")
self.qle.del_.assert_called_with()
self.bridge.rl_yank()
self.qle.insert.assert_called_with("delete test")
@ -115,7 +117,7 @@ class ReadlineBridgeTest(unittest.TestCase):
self._set_selected_text("delete test")
self.bridge.rl_kill_line()
self.qle.end.assert_called_with(True)
self.assertEqual(self.bridge.deleted[self.qle], "delete test")
self.assertEqual(self.bridge._deleted[self.qle], "delete test")
self.qle.del_.assert_called_with()
self.bridge.rl_yank()
self.qle.insert.assert_called_with("delete test")
@ -125,7 +127,7 @@ class ReadlineBridgeTest(unittest.TestCase):
self._set_selected_text("delete test")
self.bridge.rl_unix_word_rubout()
self.qle.cursorWordBackward.assert_called_with(True)
self.assertEqual(self.bridge.deleted[self.qle], "delete test")
self.assertEqual(self.bridge._deleted[self.qle], "delete test")
self.qle.del_.assert_called_with()
self.bridge.rl_yank()
self.qle.insert.assert_called_with("delete test")
@ -135,7 +137,7 @@ class ReadlineBridgeTest(unittest.TestCase):
self._set_selected_text("delete test")
self.bridge.rl_kill_word()
self.qle.cursorWordForward.assert_called_with(True)
self.assertEqual(self.bridge.deleted[self.qle], "delete test")
self.assertEqual(self.bridge._deleted[self.qle], "delete test")
self.qle.del_.assert_called_with()
self.bridge.rl_yank()
self.qle.insert.assert_called_with("delete test")

View File

@ -72,17 +72,17 @@ class DefaultTests(unittest.TestCase):
def test_simple(self):
"""Test default with a numeric argument."""
nl = usertypes.NeighborList([1, 2, 3], default=2)
self.assertEqual(nl.idx, 1)
self.assertEqual(nl._idx, 1)
def test_none(self):
"""Test default 'None'."""
nl = usertypes.NeighborList([1, 2, None], default=None)
self.assertEqual(nl.idx, 2)
self.assertEqual(nl._idx, 2)
def test_unset(self):
"""Test unset default value."""
nl = usertypes.NeighborList([1, 2, 3])
self.assertIsNone(nl.idx)
self.assertIsNone(nl._idx)
class EmptyTests(unittest.TestCase):
@ -130,48 +130,48 @@ class ItemTests(unittest.TestCase):
def test_curitem(self):
"""Test curitem()."""
self.assertEqual(self.nl.idx, 2)
self.assertEqual(self.nl._idx, 2)
self.assertEqual(self.nl.curitem(), 3)
self.assertEqual(self.nl.idx, 2)
self.assertEqual(self.nl._idx, 2)
def test_nextitem(self):
"""Test nextitem()."""
self.assertEqual(self.nl.nextitem(), 4)
self.assertEqual(self.nl.idx, 3)
self.assertEqual(self.nl._idx, 3)
self.assertEqual(self.nl.nextitem(), 5)
self.assertEqual(self.nl.idx, 4)
self.assertEqual(self.nl._idx, 4)
def test_previtem(self):
"""Test previtem()."""
self.assertEqual(self.nl.previtem(), 2)
self.assertEqual(self.nl.idx, 1)
self.assertEqual(self.nl._idx, 1)
self.assertEqual(self.nl.previtem(), 1)
self.assertEqual(self.nl.idx, 0)
self.assertEqual(self.nl._idx, 0)
def test_firstitem(self):
"""Test firstitem()."""
self.assertEqual(self.nl.firstitem(), 1)
self.assertEqual(self.nl.idx, 0)
self.assertEqual(self.nl._idx, 0)
def test_lastitem(self):
"""Test lastitem()."""
self.assertEqual(self.nl.lastitem(), 5)
self.assertEqual(self.nl.idx, 4)
self.assertEqual(self.nl._idx, 4)
def test_reset(self):
"""Test reset()."""
self.nl.nextitem()
self.assertEqual(self.nl.idx, 3)
self.assertEqual(self.nl._idx, 3)
self.nl.reset()
self.assertEqual(self.nl.idx, 2)
self.assertEqual(self.nl._idx, 2)
def test_getitem(self):
"""Test getitem()."""
self.assertEqual(self.nl.getitem(2), 5)
self.assertEqual(self.nl.idx, 4)
self.assertEqual(self.nl._idx, 4)
self.nl.reset()
self.assertEqual(self.nl.getitem(-2), 1)
self.assertEqual(self.nl.idx, 0)
self.assertEqual(self.nl._idx, 0)
class OneTests(unittest.TestCase):
@ -189,51 +189,51 @@ class OneTests(unittest.TestCase):
"""Test out of bounds previtem() with mode=wrap."""
self.nl._mode = usertypes.NeighborList.Modes.wrap
self.nl.firstitem()
self.assertEqual(self.nl.idx, 0)
self.assertEqual(self.nl._idx, 0)
self.assertEqual(self.nl.previtem(), 1)
self.assertEqual(self.nl.idx, 0)
self.assertEqual(self.nl._idx, 0)
def test_first_block(self):
"""Test out of bounds previtem() with mode=block."""
self.nl._mode = usertypes.NeighborList.Modes.block
self.nl.firstitem()
self.assertEqual(self.nl.idx, 0)
self.assertEqual(self.nl._idx, 0)
self.assertEqual(self.nl.previtem(), 1)
self.assertEqual(self.nl.idx, 0)
self.assertEqual(self.nl._idx, 0)
def test_first_raise(self):
"""Test out of bounds previtem() with mode=raise."""
self.nl._mode = usertypes.NeighborList.Modes.exception
self.nl.firstitem()
self.assertEqual(self.nl.idx, 0)
self.assertEqual(self.nl._idx, 0)
with self.assertRaises(IndexError):
self.nl.previtem()
self.assertEqual(self.nl.idx, 0)
self.assertEqual(self.nl._idx, 0)
def test_last_wrap(self):
"""Test out of bounds nextitem() with mode=wrap."""
self.nl._mode = usertypes.NeighborList.Modes.wrap
self.nl.lastitem()
self.assertEqual(self.nl.idx, 0)
self.assertEqual(self.nl._idx, 0)
self.assertEqual(self.nl.nextitem(), 1)
self.assertEqual(self.nl.idx, 0)
self.assertEqual(self.nl._idx, 0)
def test_last_block(self):
"""Test out of bounds nextitem() with mode=block."""
self.nl._mode = usertypes.NeighborList.Modes.block
self.nl.lastitem()
self.assertEqual(self.nl.idx, 0)
self.assertEqual(self.nl._idx, 0)
self.assertEqual(self.nl.nextitem(), 1)
self.assertEqual(self.nl.idx, 0)
self.assertEqual(self.nl._idx, 0)
def test_last_raise(self):
"""Test out of bounds nextitem() with mode=raise."""
self.nl._mode = usertypes.NeighborList.Modes.exception
self.nl.lastitem()
self.assertEqual(self.nl.idx, 0)
self.assertEqual(self.nl._idx, 0)
with self.assertRaises(IndexError):
self.nl.nextitem()
self.assertEqual(self.nl.idx, 0)
self.assertEqual(self.nl._idx, 0)
class BlockTests(unittest.TestCase):
@ -252,16 +252,16 @@ class BlockTests(unittest.TestCase):
def test_first(self):
"""Test ouf of bounds previtem()."""
self.nl.firstitem()
self.assertEqual(self.nl.idx, 0)
self.assertEqual(self.nl._idx, 0)
self.assertEqual(self.nl.previtem(), 1)
self.assertEqual(self.nl.idx, 0)
self.assertEqual(self.nl._idx, 0)
def test_last(self):
"""Test ouf of bounds nextitem()."""
self.nl.lastitem()
self.assertEqual(self.nl.idx, 4)
self.assertEqual(self.nl._idx, 4)
self.assertEqual(self.nl.nextitem(), 5)
self.assertEqual(self.nl.idx, 4)
self.assertEqual(self.nl._idx, 4)
class WrapTests(unittest.TestCase):
@ -279,16 +279,16 @@ class WrapTests(unittest.TestCase):
def test_first(self):
"""Test ouf of bounds previtem()."""
self.nl.firstitem()
self.assertEqual(self.nl.idx, 0)
self.assertEqual(self.nl._idx, 0)
self.assertEqual(self.nl.previtem(), 5)
self.assertEqual(self.nl.idx, 4)
self.assertEqual(self.nl._idx, 4)
def test_last(self):
"""Test ouf of bounds nextitem()."""
self.nl.lastitem()
self.assertEqual(self.nl.idx, 4)
self.assertEqual(self.nl._idx, 4)
self.assertEqual(self.nl.nextitem(), 1)
self.assertEqual(self.nl.idx, 0)
self.assertEqual(self.nl._idx, 0)
class RaiseTests(unittest.TestCase):
@ -307,18 +307,18 @@ class RaiseTests(unittest.TestCase):
def test_first(self):
"""Test ouf of bounds previtem()."""
self.nl.firstitem()
self.assertEqual(self.nl.idx, 0)
self.assertEqual(self.nl._idx, 0)
with self.assertRaises(IndexError):
self.nl.previtem()
self.assertEqual(self.nl.idx, 0)
self.assertEqual(self.nl._idx, 0)
def test_last(self):
"""Test ouf of bounds nextitem()."""
self.nl.lastitem()
self.assertEqual(self.nl.idx, 4)
self.assertEqual(self.nl._idx, 4)
with self.assertRaises(IndexError):
self.nl.nextitem()
self.assertEqual(self.nl.idx, 4)
self.assertEqual(self.nl._idx, 4)
class SnapInTests(unittest.TestCase):
@ -336,29 +336,29 @@ class SnapInTests(unittest.TestCase):
"""Test fuzzyval with snapping to a bigger value."""
self.nl.fuzzyval = 7
self.assertEqual(self.nl.nextitem(), 9)
self.assertEqual(self.nl.idx, 1)
self.assertEqual(self.nl._idx, 1)
self.assertEqual(self.nl.nextitem(), 1)
self.assertEqual(self.nl.idx, 2)
self.assertEqual(self.nl._idx, 2)
def test_smaller(self):
"""Test fuzzyval with snapping to a smaller value."""
self.nl.fuzzyval = 7
self.assertEqual(self.nl.previtem(), 5)
self.assertEqual(self.nl.idx, 3)
self.assertEqual(self.nl._idx, 3)
self.assertEqual(self.nl.previtem(), 1)
self.assertEqual(self.nl.idx, 2)
self.assertEqual(self.nl._idx, 2)
def test_equal_bigger(self):
"""Test fuzzyval with matching value, snapping to a bigger value."""
self.nl.fuzzyval = 20
self.assertEqual(self.nl.nextitem(), 9)
self.assertEqual(self.nl.idx, 1)
self.assertEqual(self.nl._idx, 1)
def test_equal_smaller(self):
"""Test fuzzyval with matching value, snapping to a smaller value."""
self.nl.fuzzyval = 5
self.assertEqual(self.nl.previtem(), 1)
self.assertEqual(self.nl.idx, 2)
self.assertEqual(self.nl._idx, 2)
if __name__ == '__main__':

View File

@ -33,7 +33,7 @@ class Completer(QObject):
"""Completer which manages completions in a CompletionView.
Attributes:
ignore_change: Whether to ignore the next completion update.
_ignore_change: Whether to ignore the next completion update.
_models: dict of available completion models.
Signals:
@ -48,8 +48,8 @@ class Completer(QObject):
change_completed_part = pyqtSignal(str, bool)
def __init__(self, parent=None):
super().__init__()
self.ignore_change = False
super().__init__(parent)
self._ignore_change = False
self._models = {
usertypes.Completion.option: {},
@ -177,9 +177,9 @@ class Completer(QObject):
# and go on to the next part.
self.change_completed_part.emit(data, True)
else:
self.ignore_change = True
self._ignore_change = True
self.change_completed_part.emit(data, False)
self.ignore_change = False
self._ignore_change = False
@pyqtSlot(str, list, int)
def on_update_completion(self, prefix, parts, cursor_part):
@ -191,7 +191,7 @@ class Completer(QObject):
text: The new text
cursor_part: The part the cursor is currently over.
"""
if self.ignore_change:
if self._ignore_change:
log.completion.debug("Ignoring completion update")
return

View File

@ -75,12 +75,13 @@ class DocstringParser:
Args:
func: The function to parse the docstring for.
"""
self.state = self.State.short
self._state = self.State.short
self._cur_arg_name = None
self.short_desc = []
self.long_desc = []
self.arg_descs = collections.OrderedDict()
self.cur_arg_name = None
self.handlers = {
doc = inspect.getdoc(func)
handlers = {
self.State.short: self._parse_short,
self.State.desc: self._parse_desc,
self.State.desc_hidden: self._skip,
@ -88,9 +89,8 @@ class DocstringParser:
self.State.arg_inside: self._parse_arg_inside,
self.State.misc: self._skip,
}
doc = inspect.getdoc(func)
for line in doc.splitlines():
handler = self.handlers[self.state]
handler = handlers[self._state]
stop = handler(line)
if stop:
break
@ -101,41 +101,41 @@ class DocstringParser:
def _process_arg(self, line):
"""Helper method to process a line like 'fooarg: Blah blub'."""
self.cur_arg_name, argdesc = line.split(':', maxsplit=1)
self.cur_arg_name = self.cur_arg_name.strip().lstrip('*')
self.arg_descs[self.cur_arg_name] = [argdesc.strip()]
self._cur_arg_name, argdesc = line.split(':', maxsplit=1)
self._cur_arg_name = self._cur_arg_name.strip().lstrip('*')
self.arg_descs[self._cur_arg_name] = [argdesc.strip()]
def _skip(self, line):
"""Handler to ignore everything until we get 'Args:'."""
if line.startswith('Args:'):
self.state = self.State.arg_start
self._state = self.State.arg_start
def _parse_short(self, line):
"""Parse the short description (first block) in the docstring."""
if not line:
self.state = self.State.desc
self._state = self.State.desc
else:
self.short_desc.append(line.strip())
def _parse_desc(self, line):
"""Parse the long description in the docstring."""
if line.startswith('Args:'):
self.state = self.State.arg_start
self._state = self.State.arg_start
elif line.startswith('Emit:') or line.startswith('Raise:'):
self.state = self.State.misc
self._state = self.State.misc
elif line.strip() == '//':
self.state = self.State.desc_hidden
self._state = self.State.desc_hidden
elif line.strip():
self.long_desc.append(line.strip())
def _parse_arg_start(self, line):
"""Parse first argument line."""
self._process_arg(line)
self.state = self.State.arg_inside
self._state = self.State.arg_inside
def _parse_arg_inside(self, line):
"""Parse subsequent argument lines."""
argname = self.cur_arg_name
argname = self._cur_arg_name
if re.match(r'^[A-Z][a-z]+:$', line):
if not self.arg_descs[argname][-1].strip():
self.arg_descs[argname] = self.arg_descs[argname][:-1]

View File

@ -36,16 +36,16 @@ class ExternalEditor(QObject):
def __init__(self, parent=None):
super().__init__(parent)
self.text = None
self.oshandle = None
self.filename = None
self.proc = None
self._text = None
self._oshandle = None
self._filename = None
self._proc = None
def _cleanup(self):
"""Clean up temporary files after the editor closed."""
os.close(self.oshandle)
os.close(self._oshandle)
try:
os.remove(self.filename)
os.remove(self._filename)
except PermissionError as e:
# NOTE: Do not replace this with "raise CommandError" as it's
# executed async.
@ -72,7 +72,7 @@ class ExternalEditor(QObject):
exitcode))
return
encoding = config.get('general', 'editor-encoding')
with open(self.filename, 'r', encoding=encoding) as f:
with open(self._filename, 'r', encoding=encoding) as f:
text = ''.join(f.readlines())
log.procs.debug("Read back: {}".format(text))
self.editing_finished.emit(text)
@ -105,19 +105,19 @@ class ExternalEditor(QObject):
Emit:
editing_finished with the new text if editing finshed successfully.
"""
if self.text is not None:
if self._text is not None:
raise ValueError("Already editing a file!")
self.text = text
self.oshandle, self.filename = tempfile.mkstemp(text=True)
self._text = text
self._oshandle, self._filename = tempfile.mkstemp(text=True)
if text:
encoding = config.get('general', 'editor-encoding')
with open(self.filename, 'w', encoding=encoding) as f:
with open(self._filename, 'w', encoding=encoding) as f:
f.write(text)
self.proc = QProcess(self)
self.proc.finished.connect(self.on_proc_closed)
self.proc.error.connect(self.on_proc_error)
self._proc = QProcess(self)
self._proc.finished.connect(self.on_proc_closed)
self._proc.error.connect(self.on_proc_error)
editor = config.get('general', 'editor')
executable = editor[0]
args = [self.filename if arg == '{}' else arg for arg in editor[1:]]
args = [self._filename if arg == '{}' else arg for arg in editor[1:]]
log.procs.debug("Calling \"{}\" with args {}".format(executable, args))
self.proc.start(executable, args)
self._proc.start(executable, args)

View File

@ -31,10 +31,10 @@ class Loader(jinja2.BaseLoader):
"""Jinja loader which uses utils.read_file to load templates."""
def __init__(self, subdir):
self.subdir = subdir
self._subdir = subdir
def get_source(self, _env, template):
path = os.path.join(self.subdir, template)
path = os.path.join(self._subdir, template)
try:
source = utils.read_file(path)
except FileNotFoundError:

View File

@ -295,21 +295,21 @@ class LogFilter(logging.Filter):
comma-separated list instead.
Attributes:
names: A list of names that should be logged.
_names: A list of names that should be logged.
"""
def __init__(self, names):
super().__init__()
self.names = names
self._names = names
def filter(self, record):
"""Determine if the specified record is to be logged."""
if self.names is None:
if self._names is None:
return True
if record.levelno > logging.DEBUG:
# More important than DEBUG, so we won't filter at all
return True
for name in self.names:
for name in self._names:
if record.name == name:
return True
elif not record.name.startswith(name):
@ -327,21 +327,21 @@ class RAMHandler(logging.Handler):
uses a simple list rather than a deque.
Attributes:
data: A deque containing the logging records.
_data: A deque containing the logging records.
"""
def __init__(self, capacity):
super().__init__()
self.html_formatter = None
if capacity != -1:
self.data = collections.deque(maxlen=capacity)
self._data = collections.deque(maxlen=capacity)
else:
self.data = collections.deque()
self._data = collections.deque()
def emit(self, record):
if record.levelno >= logging.DEBUG:
# We don't log VDEBUG to RAM.
self.data.append(record)
self._data.append(record)
def dump_log(self, html=False):
"""Dump the complete formatted log data as as string.
@ -352,7 +352,7 @@ class RAMHandler(logging.Handler):
fmt = self.html_formatter.format if html else self.format
self.acquire()
try:
records = list(self.data)
records = list(self._data)
finally:
self.release()
for record in records:

View File

@ -30,11 +30,11 @@ class ReadlineBridge:
"""Bridge which provides readline-like commands for the current QLineEdit.
Attributes:
deleted: Mapping from widgets to their last deleted text.
_deleted: Mapping from widgets to their last deleted text.
"""
def __init__(self):
self.deleted = {}
self._deleted = {}
def __repr__(self):
return '<{}>'.format(self.__class__.__name__)
@ -130,7 +130,7 @@ class ReadlineBridge:
if widget is None:
return
widget.home(True)
self.deleted[widget] = widget.selectedText()
self._deleted[widget] = widget.selectedText()
widget.del_()
@cmdutils.register(instance='readline-bridge', hide=True,
@ -144,7 +144,7 @@ class ReadlineBridge:
if widget is None:
return
widget.end(True)
self.deleted[widget] = widget.selectedText()
self._deleted[widget] = widget.selectedText()
widget.del_()
@cmdutils.register(instance='readline-bridge', hide=True,
@ -158,7 +158,7 @@ class ReadlineBridge:
if widget is None:
return
widget.cursorWordBackward(True)
self.deleted[widget] = widget.selectedText()
self._deleted[widget] = widget.selectedText()
widget.del_()
@cmdutils.register(instance='readline-bridge', hide=True,
@ -172,7 +172,7 @@ class ReadlineBridge:
if widget is None:
return
widget.cursorWordForward(True)
self.deleted[widget] = widget.selectedText()
self._deleted[widget] = widget.selectedText()
widget.del_()
@cmdutils.register(instance='readline-bridge', hide=True,
@ -183,9 +183,9 @@ class ReadlineBridge:
This acts like readline's yank.
"""
widget = self._widget()
if widget is None or widget not in self.deleted:
if widget is None or widget not in self._deleted:
return
widget.insert(self.deleted[widget])
widget.insert(self._deleted[widget])
@cmdutils.register(instance='readline-bridge', hide=True,
modes=[typ.KeyMode.command, typ.KeyMode.prompt])

View File

@ -71,8 +71,8 @@ class NeighborList(collections.abc.Sequence):
Modes: Different modes, see constructor documentation.
Attributes:
idx: The current position in the list.
fuzzyval: The value which is currently set but not in the list.
_idx: The current position in the list.
_items: A list of all items, accessed through item property.
_mode: The current mode.
"""
@ -98,9 +98,9 @@ class NeighborList(collections.abc.Sequence):
self._items = list(items)
self._default = default
if default is not _UNSET:
self.idx = self._items.index(default)
self._idx = self._items.index(default)
else:
self.idx = None
self._idx = None
self._mode = mode
self.fuzzyval = None
@ -128,7 +128,7 @@ class NeighborList(collections.abc.Sequence):
items = [(idx, e) for (idx, e) in enumerate(self._items)
if op(e, self.fuzzyval)]
close_item = min(items, key=lambda tpl: abs(self.fuzzyval - tpl[1]))
self.idx = close_item[0]
self._idx = close_item[0]
return self.fuzzyval not in self._items
def _get_new_item(self, offset):
@ -145,21 +145,21 @@ class NeighborList(collections.abc.Sequence):
exception.
"""
try:
if self.idx + offset >= 0:
new = self._items[self.idx + offset]
if self._idx + offset >= 0:
new = self._items[self._idx + offset]
else:
raise IndexError
except IndexError:
if self._mode == self.Modes.block:
new = self.curitem()
elif self._mode == self.Modes.wrap:
self.idx += offset
self.idx %= len(self.items)
self._idx += offset
self._idx %= len(self.items)
new = self.curitem()
elif self._mode == self.Modes.exception:
raise
else:
self.idx += offset
self._idx += offset
return new
@property
@ -181,7 +181,7 @@ class NeighborList(collections.abc.Sequence):
exception.
"""
log.misc.debug("{} items, idx {}, offset {}".format(
len(self._items), self.idx, offset))
len(self._items), self._idx, offset))
if not self._items:
raise IndexError("No items found!")
if self.fuzzyval is not None:
@ -198,8 +198,8 @@ class NeighborList(collections.abc.Sequence):
def curitem(self):
"""Get the current item in the list."""
if self.idx is not None:
return self._items[self.idx]
if self._idx is not None:
return self._items[self._idx]
else:
raise IndexError("No current item!")
@ -215,14 +215,14 @@ class NeighborList(collections.abc.Sequence):
"""Get the first item in the list."""
if not self._items:
raise IndexError("No items found!")
self.idx = 0
self._idx = 0
return self.curitem()
def lastitem(self):
"""Get the last item in the list."""
if not self._items:
raise IndexError("No items found!")
self.idx = len(self._items) - 1
self._idx = len(self._items) - 1
return self.curitem()
def reset(self):
@ -230,7 +230,7 @@ class NeighborList(collections.abc.Sequence):
if self._default is _UNSET:
raise ValueError("No default set!")
else:
self.idx = self._items.index(self._default)
self._idx = self._items.index(self._default)
return self.curitem()

View File

@ -532,8 +532,8 @@ class prevent_exceptions: # pylint: disable=invalid-name
much cleaner to implement.
Attributes:
retval: The value to return in case of an exception.
predicate: The condition which needs to be True to prevent exceptions
_retval: The value to return in case of an exception.
_predicate: The condition which needs to be True to prevent exceptions
"""
def __init__(self, retval, predicate=True):
@ -544,8 +544,8 @@ class prevent_exceptions: # pylint: disable=invalid-name
Args:
See class attributes.
"""
self.retval = retval
self.predicate = predicate
self._retval = retval
self._predicate = predicate
def __call__(self, func):
"""Gets called when a function should be decorated.
@ -556,10 +556,10 @@ class prevent_exceptions: # pylint: disable=invalid-name
Return:
The decorated function.
"""
if not self.predicate:
if not self._predicate:
return func
retval = self.retval
retval = self._retval
@functools.wraps(func)
def wrapper(*args, **kwargs): # pylint: disable=missing-docstring

View File

@ -56,7 +56,7 @@ class ConsoleLineEdit(misc.CommandLineEdit):
'self': parent,
}
self._interpreter = code.InteractiveInterpreter(interpreter_locals)
self.history = cmdhistory.History()
self._history = cmdhistory.History()
self.returnPressed.connect(self.execute)
self.setText('')
@ -67,10 +67,10 @@ class ConsoleLineEdit(misc.CommandLineEdit):
@pyqtSlot(str)
def execute(self):
"""Execute the line of code which was entered."""
self.history.stop()
self._history.stop()
text = self.text()
if text:
self.history.append(text)
self._history.append(text)
self.push(text)
self.setText('')
@ -95,10 +95,10 @@ class ConsoleLineEdit(misc.CommandLineEdit):
def history_prev(self):
"""Go back in the history."""
try:
if not self.history.is_browsing():
item = self.history.start(self.text().strip())
if not self._history.is_browsing():
item = self._history.start(self.text().strip())
else:
item = self.history.previtem()
item = self._history.previtem()
except (cmdhistory.HistoryEmptyError,
cmdhistory.HistoryEndReachedError):
return
@ -106,10 +106,10 @@ class ConsoleLineEdit(misc.CommandLineEdit):
def history_next(self):
"""Go forward in the history."""
if not self.history.is_browsing():
if not self._history.is_browsing():
return
try:
item = self.history.nextitem()
item = self._history.nextitem()
except cmdhistory.HistoryEndReachedError:
return
self.setText(item)
@ -166,15 +166,15 @@ class ConsoleWidget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.lineedit = ConsoleLineEdit(self)
self.output = ConsoleTextEdit()
self.lineedit.write.connect(self.output.append)
self.vbox = QVBoxLayout()
self.vbox.setSpacing(0)
self.vbox.addWidget(self.output)
self.vbox.addWidget(self.lineedit)
self.setLayout(self.vbox)
self.lineedit.setFocus()
self._lineedit = ConsoleLineEdit(self)
self._output = ConsoleTextEdit()
self._lineedit.write.connect(self._output.append)
self._vbox = QVBoxLayout()
self._vbox.setSpacing(0)
self._vbox.addWidget(self._output)
self._vbox.addWidget(self._lineedit)
self.setLayout(self._vbox)
self._lineedit.setFocus()
def __repr__(self):
return '<{}, visible={}>'.format(
@ -183,5 +183,5 @@ class ConsoleWidget(QWidget):
@pyqtSlot(str, str)
def on_config_changed(self, section, option):
"""Update font when config changed."""
self.lineedit.on_config_changed(section, option)
self.output.on_config_changed(section, option)
self._lineedit.on_config_changed(section, option)
self._output.on_config_changed(section, option)

View File

@ -41,7 +41,7 @@ class MainWindow(QWidget):
Attributes:
status: The StatusBar widget.
downloadview: The DownloadView widget.
_downloadview: The DownloadView widget.
_tabbed_browser: The TabbedBrowser widget.
_vbox: The main QVBoxLayout.
"""
@ -77,9 +77,9 @@ class MainWindow(QWidget):
self._vbox.setContentsMargins(0, 0, 0, 0)
self._vbox.setSpacing(0)
self.downloadview = downloads.DownloadView()
self._vbox.addWidget(self.downloadview)
self.downloadview.show()
self._downloadview = downloads.DownloadView()
self._vbox.addWidget(self._downloadview)
self._downloadview.show()
self._tabbed_browser = tabbedbrowser.TabbedBrowser()
self._tabbed_browser.title_changed.connect(self.setWindowTitle)
@ -164,7 +164,7 @@ class MainWindow(QWidget):
"""
super().resizeEvent(e)
self.resize_completion()
self.downloadview.updateGeometry()
self._downloadview.updateGeometry()
self._tabbed_browser.tabBar().refresh()
def closeEvent(self, e):

View File

@ -73,7 +73,7 @@ class Command(misc.MinimalLineEditMixin, misc.CommandLineEdit):
def __init__(self, parent=None):
misc.CommandLineEdit.__init__(self, parent)
misc.MinimalLineEditMixin.__init__(self)
self.cursor_part = 0
self._cursor_part = 0
self.history.history = objreg.get('command-history').data
self._empty_item_idx = None
self.textEdited.connect(self.on_text_edited)
@ -124,7 +124,7 @@ class Command(misc.MinimalLineEditMixin, misc.CommandLineEdit):
for i, part in enumerate(self.split()):
if cursor_pos <= len(part):
# foo| bar
self.cursor_part = i
self._cursor_part = i
if spaces:
self._empty_item_idx = i
else:
@ -132,14 +132,14 @@ class Command(misc.MinimalLineEditMixin, misc.CommandLineEdit):
break
cursor_pos -= (len(part) + 1) # FIXME are spaces always 1 char?
log.completion.debug("cursor_part {}, spaces {}".format(
self.cursor_part, spaces))
self._cursor_part, spaces))
return
@pyqtSlot()
def on_cursor_position_changed(self):
"""Update completion when the cursor position changed."""
self.update_completion.emit(self.prefix(), self.split(),
self.cursor_part)
self._cursor_part)
@pyqtSlot(str)
def set_cmd_text(self, text):
@ -156,7 +156,7 @@ class Command(misc.MinimalLineEditMixin, misc.CommandLineEdit):
if old_text != text:
# We want the completion to pop out here.
self.update_completion.emit(self.prefix(), self.split(),
self.cursor_part)
self._cursor_part)
self.setFocus()
self.show_cmd.emit()
@ -196,16 +196,16 @@ class Command(misc.MinimalLineEditMixin, misc.CommandLineEdit):
"""
parts = self.split()
log.completion.debug("changing part {} to '{}'".format(
self.cursor_part, newtext))
parts[self.cursor_part] = newtext
self._cursor_part, newtext))
parts[self._cursor_part] = newtext
# We want to place the cursor directly after the part we just changed.
cursor_str = self.prefix() + ' '.join(parts[:self.cursor_part + 1])
cursor_str = self.prefix() + ' '.join(parts[:self._cursor_part + 1])
if immediate:
# If we should complete immediately, we want to move the cursor by
# one more char, to get to the next field.
cursor_str += ' '
text = self.prefix() + ' '.join(parts)
if immediate and self.cursor_part == len(parts) - 1:
if immediate and self._cursor_part == len(parts) - 1:
# If we should complete immediately and we're completing the last
# part in the commandline, we automatically add a space.
text += ' '

View File

@ -57,7 +57,7 @@ class Prompter:
up the *new* question.
Attributes:
question: A Question object with the question to be asked to the user.
_question: A Question object with the question to be asked to the user.
_loops: A list of local EventLoops to spin in when blocking.
_queue: A deque of waiting questions.
"""
@ -86,7 +86,7 @@ class Prompter:
if not self._busy:
return None
prompt = objreg.get('prompt')
ctx = PromptContext(question=self.question,
ctx = PromptContext(question=self._question,
text=prompt.txt.text(),
input_text=prompt.lineedit.text(),
echo_mode=prompt.lineedit.echoMode(),
@ -107,7 +107,7 @@ class Prompter:
prompt.hide_prompt.emit()
self._busy = False
return False
self.question = ctx.question
self._question = ctx.question
prompt.txt.setText(ctx.text)
prompt.lineedit.setText(ctx.input_text)
prompt.lineedit.setEchoMode(ctx.echo_mode)
@ -115,7 +115,7 @@ class Prompter:
return True
def _display_question(self):
"""Display the question saved in self.question.
"""Display the question saved in self._question.
Return:
The mode which should be entered.
@ -124,30 +124,30 @@ class Prompter:
ValueError if the set PromptMode is invalid.
"""
prompt = objreg.get('prompt')
if self.question.mode == usertypes.PromptMode.yesno:
if self.question.default is None:
if self._question.mode == usertypes.PromptMode.yesno:
if self._question.default is None:
suffix = ""
elif self.question.default:
elif self._question.default:
suffix = " (yes)"
else:
suffix = " (no)"
prompt.txt.setText(self.question.text + suffix)
prompt.txt.setText(self._question.text + suffix)
prompt.lineedit.hide()
mode = usertypes.KeyMode.yesno
elif self.question.mode == usertypes.PromptMode.text:
prompt.txt.setText(self.question.text)
if self.question.default:
prompt.lineedit.setText(self.question.default)
elif self._question.mode == usertypes.PromptMode.text:
prompt.txt.setText(self._question.text)
if self._question.default:
prompt.lineedit.setText(self._question.default)
prompt.lineedit.show()
mode = usertypes.KeyMode.prompt
elif self.question.mode == usertypes.PromptMode.user_pwd:
prompt.txt.setText(self.question.text)
if self.question.default:
prompt.lineedit.setText(self.question.default)
elif self._question.mode == usertypes.PromptMode.user_pwd:
prompt.txt.setText(self._question.text)
if self._question.default:
prompt.lineedit.setText(self._question.default)
prompt.lineedit.show()
mode = usertypes.KeyMode.prompt
elif self.question.mode == usertypes.PromptMode.alert:
prompt.txt.setText(self.question.text + ' (ok)')
elif self._question.mode == usertypes.PromptMode.alert:
prompt.txt.setText(self._question.text + ' (ok)')
prompt.lineedit.hide()
mode = usertypes.KeyMode.prompt
else:
@ -184,8 +184,8 @@ class Prompter:
prompt.lineedit.setEchoMode(QLineEdit.Normal)
prompt.hide_prompt.emit()
self._busy = False
if self.question.answer is None and not self.question.is_aborted:
self.question.cancel()
if self._question.answer is None and not self._question.is_aborted:
self._question.cancel()
@cmdutils.register(instance='prompter', hide=True,
modes=[usertypes.KeyMode.prompt,
@ -199,34 +199,34 @@ class Prompter:
for the password or leaves the mode.
"""
prompt = objreg.get('prompt')
if (self.question.mode == usertypes.PromptMode.user_pwd and
self.question.user is None):
if (self._question.mode == usertypes.PromptMode.user_pwd and
self._question.user is None):
# User just entered an username
self.question.user = prompt.lineedit.text()
self._question.user = prompt.lineedit.text()
prompt.txt.setText("Password:")
prompt.lineedit.clear()
prompt.lineedit.setEchoMode(QLineEdit.Password)
elif self.question.mode == usertypes.PromptMode.user_pwd:
elif self._question.mode == usertypes.PromptMode.user_pwd:
# User just entered a password
password = prompt.lineedit.text()
self.question.answer = (self.question.user, password)
self._question.answer = (self._question.user, password)
modeman.leave(usertypes.KeyMode.prompt, 'prompt accept')
self.question.done()
elif self.question.mode == usertypes.PromptMode.text:
self._question.done()
elif self._question.mode == usertypes.PromptMode.text:
# User just entered text.
self.question.answer = prompt.lineedit.text()
self._question.answer = prompt.lineedit.text()
modeman.leave(usertypes.KeyMode.prompt, 'prompt accept')
self.question.done()
elif self.question.mode == usertypes.PromptMode.yesno:
self._question.done()
elif self._question.mode == usertypes.PromptMode.yesno:
# User wants to accept the default of a yes/no question.
self.question.answer = self.question.default
self._question.answer = self._question.default
modeman.leave(usertypes.KeyMode.yesno, 'yesno accept')
self.question.done()
elif self.question.mode == usertypes.PromptMode.alert:
self._question.done()
elif self._question.mode == usertypes.PromptMode.alert:
# User acknowledged an alert
self.question.answer = None
self._question.answer = None
modeman.leave(usertypes.KeyMode.prompt, 'alert accept')
self.question.done()
self._question.done()
else:
raise ValueError("Invalid question mode!")
@ -234,23 +234,23 @@ class Prompter:
modes=[usertypes.KeyMode.yesno])
def prompt_yes(self):
"""Answer yes to a yes/no prompt."""
if self.question.mode != usertypes.PromptMode.yesno:
if self._question.mode != usertypes.PromptMode.yesno:
# We just ignore this if we don't have a yes/no question.
return
self.question.answer = True
self._question.answer = True
modeman.leave(usertypes.KeyMode.yesno, 'yesno accept')
self.question.done()
self._question.done()
@cmdutils.register(instance='prompter', hide=True,
modes=[usertypes.KeyMode.yesno])
def prompt_no(self):
"""Answer no to a yes/no prompt."""
if self.question.mode != usertypes.PromptMode.yesno:
if self._question.mode != usertypes.PromptMode.yesno:
# We just ignore this if we don't have a yes/no question.
return
self.question.answer = False
self._question.answer = False
modeman.leave(usertypes.KeyMode.yesno, 'prompt accept')
self.question.done()
self._question.done()
@pyqtSlot(usertypes.Question, bool)
def ask_question(self, question, blocking):
@ -280,7 +280,7 @@ class Prompter:
# restore it after exec, if exec gets called multiple times.
context = self._get_ctx()
self.question = question
self._question = question
mode = self._display_question()
question.aborted.connect(lambda: modeman.maybe_leave(mode, 'aborted'))
mode_manager = objreg.get('mode-manager')
@ -303,6 +303,6 @@ class Prompter:
# questions.
if self._queue:
self._pop_later()
return self.question.answer
return self._question.answer
else:
question.completed.connect(self._pop_later)