Add a bunch of missing python docstrings.

This appeases pylint, so un-disable its docstring warning.
This commit is contained in:
Avery Pennarun 2018-12-14 08:38:53 +00:00
commit 29f939013e
23 changed files with 89 additions and 4 deletions

View file

@ -11,7 +11,7 @@ jobs=1
# We probably want to fix these eventually, but in the meantime, these # We probably want to fix these eventually, but in the meantime, these
# ones are relatively harmless. # ones are relatively harmless.
disable=multiple-imports,missing-docstring,locally-disabled,invalid-name,unused-argument,fixme,global-statement,redefined-variable-type,using-constant-test,unused-variable,file-ignored,simplifiable-if-statement disable=multiple-imports,locally-disabled,invalid-name,unused-argument,fixme,global-statement,redefined-variable-type,using-constant-test,unused-variable,file-ignored,simplifiable-if-statement
[REPORTS] [REPORTS]
@ -159,7 +159,7 @@ method-name-hint=[a-z_][a-z0-9_]{2,30}$
# Regular expression which should only match function or class names that do # Regular expression which should only match function or class names that do
# not require a docstring. # not require a docstring.
no-docstring-rgx=^_ no-docstring-rgx=^_|^main$
# Minimum line length for functions/classes that require docstrings, shorter # Minimum line length for functions/classes that require docstrings, shorter
# ones are exempt. # ones are exempt.

View file

@ -1,5 +1,7 @@
"""Simple integer conversion helper."""
def atoi(v): def atoi(v):
"""Convert v to an integer, or return 0 on error, like C's atoi()."""
try: try:
return int(v or 0) return int(v or 0)
except ValueError: except ValueError:

View file

@ -1,3 +1,4 @@
"""redo-always: tell redo that the current target is always out of date."""
import sys, os import sys, os
from . import env, logs, state from . import env, logs, state

View file

@ -1,3 +1,4 @@
"""redo-ifchange: build the given targets if they have changed."""
import os, sys, traceback import os, sys, traceback
from . import env, builder, deps, jobserver, logs, state from . import env, builder, deps, jobserver, logs, state
from .logs import debug2, err from .logs import debug2, err

View file

@ -1,3 +1,4 @@
"""redo-ifcreate: build the current target if these targets are created."""
import sys, os import sys, os
from . import env, logs, state from . import env, logs, state
from .logs import err from .logs import err

View file

@ -1,3 +1,4 @@
"""redo-log: print past build logs. """
import errno, fcntl, os, re, struct, sys, time import errno, fcntl, os, re, struct, sys, time
import termios import termios
from .atoi import atoi from .atoi import atoi
@ -60,6 +61,10 @@ def _rel(top, mydir, path):
def catlog(t): def catlog(t):
"""Copy the given log content to our current log output device.
Note: this function's behaviour depends on global command-line options.
"""
global total_lines, status global total_lines, status
if t in already: if t in already:
return return

View file

@ -1,3 +1,4 @@
"""redo-ood: list out-of-date (ood) targets."""
import sys, os import sys, os
from . import deps, env, logs, state from . import deps, env, logs, state

View file

@ -1,3 +1,4 @@
"""redo: build the listed targets whether they need it or not."""
# #
# Copyright 2010-2018 Avery Pennarun and contributors # Copyright 2010-2018 Avery Pennarun and contributors
# #

View file

@ -1,3 +1,4 @@
"""redo-sources: list the known source (not target) files."""
import sys, os import sys, os
from . import env, logs, state from . import env, logs, state

View file

@ -1,3 +1,4 @@
"""redo-stamp: tell redo to use a checksum when considering this target."""
import sys, os import sys, os
from . import env, logs, state from . import env, logs, state
from .logs import debug2 from .logs import debug2

View file

@ -1,3 +1,4 @@
"""redo-targets: list the known targets (not sources)."""
import sys, os import sys, os
from . import env, logs, state from . import env, logs, state

View file

@ -1,3 +1,4 @@
"""redo-unlocked: internal tool for building dependencies."""
import sys, os import sys, os
from . import env, logs, state from . import env, logs, state

View file

@ -1,3 +1,4 @@
"""redo-whichdo: list the set of .do files considered to build a target."""
import sys, os import sys, os
from . import env, logs, paths from . import env, logs, paths
from .logs import err from .logs import err

View file

@ -1,3 +1,4 @@
"""Code for checking redo target dependencies."""
import os import os
from . import cycles, env, state from . import cycles, env, state
from .logs import debug from .logs import debug
@ -10,6 +11,29 @@ def isdirty(f, depth, max_changed,
is_checked=state.File.is_checked, is_checked=state.File.is_checked,
set_checked=state.File.set_checked_save, set_checked=state.File.set_checked_save,
log_override=state.warn_override): log_override=state.warn_override):
"""Determine if the given state.File needs to be built.
Args:
f: a state.File representing the target to check.
depth: a string of whitespace representing the recursion depth
(initially '')
max_changed: initially the current runid. If a target is newer than
this, anything that depends on it is considered outdated.
already_checked: initially []. A list of dependencies already
checked in this recursive cycle, to avoid infinite loops.
is_checked: a function that returns whether a given state.File has
already been checked for dirtiness.
set_checked: a function that marks a given state.File as having now
been checked for dirtiness.
log_override: a function that logs a "manual override" warning when
needed. (redo-ood replaces this with a no-op.)
Returns:
[targets...] if we won't be sure until the given list of targets has
been built.
DIRTY if the given target is definitely dirty.
CLEAN if the given target is definitely not dirty.
"""
if f.id in already_checked: if f.id in already_checked:
raise cycles.CyclicDependencyError() raise cycles.CyclicDependencyError()
# make a copy of the list, so upon returning, our parent's copy # make a copy of the list, so upon returning, our parent's copy

View file

@ -1,3 +1,4 @@
"""Manage redo-related environment variables."""
import os, sys import os, sys
from .atoi import atoi from .atoi import atoi

View file

@ -1,3 +1,4 @@
"""Some helper functions that don't fit anywhere else."""
import os, errno, fcntl import os, errno, fcntl

View file

@ -1,5 +1,4 @@
# """Implementation of a GNU make-compatible jobserver."""
# Implementation of a GNU make-compatible jobserver.
# #
# The basic idea is that both ends of a pipe (tokenfds) are shared with all # The basic idea is that both ends of a pipe (tokenfds) are shared with all
# subprocesses. At startup, we write one "token" into the pipe for each # subprocesses. At startup, we write one "token" into the pipe for each
@ -201,6 +200,7 @@ def _try_read_all(fd, n):
def setup(maxjobs): def setup(maxjobs):
"""Start the jobserver (if it isn't already) with the given token count."""
global _tokenfds, _cheatfds, _toplevel global _tokenfds, _cheatfds, _toplevel
assert maxjobs > 0 assert maxjobs > 0
assert not _tokenfds assert not _tokenfds

View file

@ -1,3 +1,4 @@
"""Code for writing log-formatted messages to stderr."""
import os, re, sys, time import os, re, sys, time
from . import env from . import env
@ -24,6 +25,8 @@ def _check_tty(tty, color):
class RawLog(object): class RawLog(object):
"""A log printer for machine-readable logs, suitable for redo-log."""
def __init__(self, tty): def __init__(self, tty):
self.file = tty self.file = tty
@ -39,6 +42,8 @@ REDO_RE = re.compile(r'@@REDO:([^@]+)@@ (.*)$')
class PrettyLog(object): class PrettyLog(object):
"""A log printer for human-readable logs."""
def __init__(self, tty): def __init__(self, tty):
self.topdir = os.getcwd() self.topdir = os.getcwd()
self.file = tty self.file = tty
@ -53,6 +58,7 @@ class PrettyLog(object):
BOLD if color else '', s, PLAIN, '\n'])) BOLD if color else '', s, PLAIN, '\n']))
def write(self, s): def write(self, s):
"""Write the string 's' to the log."""
assert '\n' not in s assert '\n' not in s
sys.stdout.flush() sys.stdout.flush()
sys.stderr.flush() sys.stderr.flush()

View file

@ -1,3 +1,4 @@
"""Code for manipulating file paths."""
import os import os
from . import env from . import env
from .logs import debug2 from .logs import debug2
@ -14,6 +15,7 @@ def _default_do_files(filename):
def possible_do_files(t): def possible_do_files(t):
"""Yield a list of tuples describing the .do file needed to build t."""
dirname, filename = os.path.split(t) dirname, filename = os.path.split(t)
yield (os.path.join(env.v.BASE, dirname), "%s.do" % filename, yield (os.path.join(env.v.BASE, dirname), "%s.do" % filename,
'', filename, '') '', filename, '')

View file

@ -1,3 +1,4 @@
"""Code for manipulating redo's state database."""
import sys, os, errno, stat, fcntl, sqlite3 import sys, os, errno, stat, fcntl, sqlite3
from . import cycles, env from . import cycles, env
from .helpers import unlink, close_on_exec, join from .helpers import unlink, close_on_exec, join
@ -31,6 +32,7 @@ _lockfile = None
_db = None _db = None
def db(): def db():
"""Initialize the state database and return its object."""
global _db, _lockfile global _db, _lockfile
if _db: if _db:
return _db return _db
@ -151,6 +153,7 @@ def check_sane():
_cwd = None _cwd = None
def relpath(t, base): def relpath(t, base):
"""Given a relative or absolute path t, express it relative to base."""
global _cwd global _cwd
if not _cwd: if not _cwd:
_cwd = os.getcwd() _cwd = os.getcwd()
@ -210,6 +213,8 @@ _file_cols = ['rowid', 'name', 'is_generated', 'is_override',
'checked_runid', 'changed_runid', 'failed_runid', 'checked_runid', 'changed_runid', 'failed_runid',
'stamp', 'csum'] 'stamp', 'csum']
class File(object): class File(object):
"""An object representing a source or target in the redo database."""
# use this mostly to avoid accidentally assigning to typos # use this mostly to avoid accidentally assigning to typos
__slots__ = ['id'] + _file_cols[1:] __slots__ = ['id'] + _file_cols[1:]
@ -324,6 +329,7 @@ class File(object):
self.set_changed() self.set_changed()
def is_source(self): def is_source(self):
"""Returns true if this object represents a source (not a target)."""
if self.name.startswith('//'): if self.name.startswith('//'):
return False # special name, ignore return False # special name, ignore
newstamp = self.read_stamp() newstamp = self.read_stamp()
@ -341,6 +347,7 @@ class File(object):
return True return True
def is_target(self): def is_target(self):
"""Returns true if this object represents a target (not a source)."""
if not self.is_generated: if not self.is_generated:
return False return False
if self.is_source(): if self.is_source():
@ -357,6 +364,7 @@ class File(object):
return self.failed_runid and self.failed_runid >= env.v.RUNID return self.failed_runid and self.failed_runid >= env.v.RUNID
def deps(self): def deps(self):
"""Return the list of objects that this object depends on."""
if self.is_override or not self.is_generated: if self.is_override or not self.is_generated:
return return
q = ('select Deps.mode, Deps.source, %s ' q = ('select Deps.mode, Deps.source, %s '
@ -370,10 +378,21 @@ class File(object):
yield mode, File(cols=cols) yield mode, File(cols=cols)
def zap_deps1(self): def zap_deps1(self):
"""Mark the list of dependencies of this object as deprecated.
We do this when starting a new build of the current target. We don't
delete them right away, because if the build fails, we still want to
know the old deps.
"""
debug2('zap-deps1: %r\n' % self.name) debug2('zap-deps1: %r\n' % self.name)
_write('update Deps set delete_me=? where target=?', [True, self.id]) _write('update Deps set delete_me=? where target=?', [True, self.id])
def zap_deps2(self): def zap_deps2(self):
"""Delete any deps that were *not* referenced in the current run.
Dependencies of a given target can change from one build to the next.
We forget old dependencies only after a build completes successfully.
"""
debug2('zap-deps2: %r\n' % self.name) debug2('zap-deps2: %r\n' % self.name)
_write('delete from Deps where target=? and delete_me=1', [self.id]) _write('delete from Deps where target=? and delete_me=1', [self.id])
@ -438,7 +457,10 @@ def logname(fid):
# The makes debugging a bit harder. When we someday port to C, we can do that. # The makes debugging a bit harder. When we someday port to C, we can do that.
_locks = {} _locks = {}
class Lock(object): class Lock(object):
"""An object representing a lock on a redo target file."""
def __init__(self, fid): def __init__(self, fid):
"""Initialize a lock, given the target's state.File.id."""
self.owned = False self.owned = False
self.fid = fid self.fid = fid
assert _lockfile >= 0 assert _lockfile >= 0
@ -451,10 +473,12 @@ class Lock(object):
self.unlock() self.unlock()
def check(self): def check(self):
"""Check that this lock is in a sane state."""
assert not self.owned assert not self.owned
cycles.check(self.fid) cycles.check(self.fid)
def trylock(self): def trylock(self):
"""Non-blocking try to acquire our lock; returns true if it worked."""
self.check() self.check()
assert not self.owned assert not self.owned
try: try:
@ -469,6 +493,12 @@ class Lock(object):
return self.owned return self.owned
def waitlock(self, shared=False): def waitlock(self, shared=False):
"""Try to acquire our lock, and wait if it's currently locked.
If shared=True, acquires a shared lock (which can be shared with
other shared locks; used by redo-log). Otherwise, acquires an
exclusive lock.
"""
self.check() self.check()
assert not self.owned assert not self.owned
fcntl.lockf( fcntl.lockf(
@ -478,6 +508,7 @@ class Lock(object):
self.owned = True self.owned = True
def unlock(self): def unlock(self):
"""Release the lock, which we must currently own."""
if not self.owned: if not self.owned:
raise Exception("can't unlock %r - we don't own it" raise Exception("can't unlock %r - we don't own it"
% self.fid) % self.fid)

View file

@ -1,3 +1,4 @@
"""Code for manipulating the Unix process title."""
import os, sys import os, sys
# FIXME: setproctitle module is only usable if *not* using python -S, # FIXME: setproctitle module is only usable if *not* using python -S,

View file

@ -1 +1,2 @@
"""A module which provides current redo version information from git."""
from ._version import COMMIT, TAG, DATE from ._version import COMMIT, TAG, DATE

View file

@ -1,3 +1,4 @@
redo-ifchange vars redo-ifchange vars
echo '"""Auto-generated file with git version information."""'
echo "# pylint: disable=bad-whitespace" echo "# pylint: disable=bad-whitespace"
cat vars cat vars