Skip to content

Commit

Permalink
Add a bunch of missing python docstrings.
Browse files Browse the repository at this point in the history
This appeases pylint, so un-disable its docstring warning.
  • Loading branch information
apenwarr committed Dec 14, 2018
1 parent 39e0178 commit 29f9390
Show file tree
Hide file tree
Showing 23 changed files with 89 additions and 4 deletions.
4 changes: 2 additions & 2 deletions .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs=1

# We probably want to fix these eventually, but in the meantime, these
# 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]
Expand Down Expand Up @@ -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
# not require a docstring.
no-docstring-rgx=^_
no-docstring-rgx=^_|^main$

# Minimum line length for functions/classes that require docstrings, shorter
# ones are exempt.
Expand Down
2 changes: 2 additions & 0 deletions redo/atoi.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""Simple integer conversion helper."""

def atoi(v):
"""Convert v to an integer, or return 0 on error, like C's atoi()."""
try:
return int(v or 0)
except ValueError:
Expand Down
1 change: 1 addition & 0 deletions redo/cmd_always.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""redo-always: tell redo that the current target is always out of date."""
import sys, os
from . import env, logs, state

Expand Down
1 change: 1 addition & 0 deletions redo/cmd_ifchange.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""redo-ifchange: build the given targets if they have changed."""
import os, sys, traceback
from . import env, builder, deps, jobserver, logs, state
from .logs import debug2, err
Expand Down
1 change: 1 addition & 0 deletions redo/cmd_ifcreate.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""redo-ifcreate: build the current target if these targets are created."""
import sys, os
from . import env, logs, state
from .logs import err
Expand Down
5 changes: 5 additions & 0 deletions redo/cmd_log.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""redo-log: print past build logs. """
import errno, fcntl, os, re, struct, sys, time
import termios
from .atoi import atoi
Expand Down Expand Up @@ -60,6 +61,10 @@ def _rel(top, mydir, path):


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
if t in already:
return
Expand Down
1 change: 1 addition & 0 deletions redo/cmd_ood.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""redo-ood: list out-of-date (ood) targets."""
import sys, os
from . import deps, env, logs, state

Expand Down
1 change: 1 addition & 0 deletions redo/cmd_redo.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""redo: build the listed targets whether they need it or not."""
#
# Copyright 2010-2018 Avery Pennarun and contributors
#
Expand Down
1 change: 1 addition & 0 deletions redo/cmd_sources.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""redo-sources: list the known source (not target) files."""
import sys, os
from . import env, logs, state

Expand Down
1 change: 1 addition & 0 deletions redo/cmd_stamp.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""redo-stamp: tell redo to use a checksum when considering this target."""
import sys, os
from . import env, logs, state
from .logs import debug2
Expand Down
1 change: 1 addition & 0 deletions redo/cmd_targets.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""redo-targets: list the known targets (not sources)."""
import sys, os
from . import env, logs, state

Expand Down
1 change: 1 addition & 0 deletions redo/cmd_unlocked.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""redo-unlocked: internal tool for building dependencies."""
import sys, os
from . import env, logs, state

Expand Down
1 change: 1 addition & 0 deletions redo/cmd_whichdo.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""redo-whichdo: list the set of .do files considered to build a target."""
import sys, os
from . import env, logs, paths
from .logs import err
Expand Down
24 changes: 24 additions & 0 deletions redo/deps.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""Code for checking redo target dependencies."""
import os
from . import cycles, env, state
from .logs import debug
Expand All @@ -10,6 +11,29 @@ def isdirty(f, depth, max_changed,
is_checked=state.File.is_checked,
set_checked=state.File.set_checked_save,
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:
raise cycles.CyclicDependencyError()
# make a copy of the list, so upon returning, our parent's copy
Expand Down
1 change: 1 addition & 0 deletions redo/env.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""Manage redo-related environment variables."""
import os, sys
from .atoi import atoi

Expand Down
1 change: 1 addition & 0 deletions redo/helpers.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""Some helper functions that don't fit anywhere else."""
import os, errno, fcntl


Expand Down
4 changes: 2 additions & 2 deletions redo/jobserver.py
Original file line number Diff line number Diff line change
@@ -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
# subprocesses. At startup, we write one "token" into the pipe for each
Expand Down Expand Up @@ -201,6 +200,7 @@ def _try_read_all(fd, n):


def setup(maxjobs):
"""Start the jobserver (if it isn't already) with the given token count."""
global _tokenfds, _cheatfds, _toplevel
assert maxjobs > 0
assert not _tokenfds
Expand Down
6 changes: 6 additions & 0 deletions redo/logs.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""Code for writing log-formatted messages to stderr."""
import os, re, sys, time
from . import env

Expand All @@ -24,6 +25,8 @@ def _check_tty(tty, color):


class RawLog(object):
"""A log printer for machine-readable logs, suitable for redo-log."""

def __init__(self, tty):
self.file = tty

Expand All @@ -39,6 +42,8 @@ def write(self, s):


class PrettyLog(object):
"""A log printer for human-readable logs."""

def __init__(self, tty):
self.topdir = os.getcwd()
self.file = tty
Expand All @@ -53,6 +58,7 @@ def _pretty(self, pid, color, s):
BOLD if color else '', s, PLAIN, '\n']))

def write(self, s):
"""Write the string 's' to the log."""
assert '\n' not in s
sys.stdout.flush()
sys.stderr.flush()
Expand Down
2 changes: 2 additions & 0 deletions redo/paths.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""Code for manipulating file paths."""
import os
from . import env
from .logs import debug2
Expand All @@ -14,6 +15,7 @@ def _default_do_files(filename):


def possible_do_files(t):
"""Yield a list of tuples describing the .do file needed to build t."""
dirname, filename = os.path.split(t)
yield (os.path.join(env.v.BASE, dirname), "%s.do" % filename,
'', filename, '')
Expand Down
31 changes: 31 additions & 0 deletions redo/state.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""Code for manipulating redo's state database."""
import sys, os, errno, stat, fcntl, sqlite3
from . import cycles, env
from .helpers import unlink, close_on_exec, join
Expand Down Expand Up @@ -31,6 +32,7 @@ def _connect(dbfile):

_db = None
def db():
"""Initialize the state database and return its object."""
global _db, _lockfile
if _db:
return _db
Expand Down Expand Up @@ -151,6 +153,7 @@ def check_sane():

_cwd = None
def relpath(t, base):
"""Given a relative or absolute path t, express it relative to base."""
global _cwd
if not _cwd:
_cwd = os.getcwd()
Expand Down Expand Up @@ -210,6 +213,8 @@ def warn_override(name):
'checked_runid', 'changed_runid', 'failed_runid',
'stamp', 'csum']
class File(object):
"""An object representing a source or target in the redo database."""

# use this mostly to avoid accidentally assigning to typos
__slots__ = ['id'] + _file_cols[1:]

Expand Down Expand Up @@ -324,6 +329,7 @@ def update_stamp(self, must_exist=False):
self.set_changed()

def is_source(self):
"""Returns true if this object represents a source (not a target)."""
if self.name.startswith('//'):
return False # special name, ignore
newstamp = self.read_stamp()
Expand All @@ -341,6 +347,7 @@ def is_source(self):
return True

def is_target(self):
"""Returns true if this object represents a target (not a source)."""
if not self.is_generated:
return False
if self.is_source():
Expand All @@ -357,6 +364,7 @@ def is_failed(self):
return self.failed_runid and self.failed_runid >= env.v.RUNID

def deps(self):
"""Return the list of objects that this object depends on."""
if self.is_override or not self.is_generated:
return
q = ('select Deps.mode, Deps.source, %s '
Expand All @@ -370,10 +378,21 @@ def deps(self):
yield mode, File(cols=cols)

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)
_write('update Deps set delete_me=? where target=?', [True, self.id])

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)
_write('delete from Deps where target=? and delete_me=1', [self.id])

Expand Down Expand Up @@ -438,7 +457,10 @@ def logname(fid):
# The makes debugging a bit harder. When we someday port to C, we can do that.
_locks = {}
class Lock(object):
"""An object representing a lock on a redo target file."""

def __init__(self, fid):
"""Initialize a lock, given the target's state.File.id."""
self.owned = False
self.fid = fid
assert _lockfile >= 0
Expand All @@ -451,10 +473,12 @@ def __del__(self):
self.unlock()

def check(self):
"""Check that this lock is in a sane state."""
assert not self.owned
cycles.check(self.fid)

def trylock(self):
"""Non-blocking try to acquire our lock; returns true if it worked."""
self.check()
assert not self.owned
try:
Expand All @@ -469,6 +493,12 @@ def trylock(self):
return self.owned

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()
assert not self.owned
fcntl.lockf(
Expand All @@ -478,6 +508,7 @@ def waitlock(self, shared=False):
self.owned = True

def unlock(self):
"""Release the lock, which we must currently own."""
if not self.owned:
raise Exception("can't unlock %r - we don't own it"
% self.fid)
Expand Down
1 change: 1 addition & 0 deletions redo/title.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""Code for manipulating the Unix process title."""
import os, sys

# FIXME: setproctitle module is only usable if *not* using python -S,
Expand Down
1 change: 1 addition & 0 deletions redo/version/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
"""A module which provides current redo version information from git."""
from ._version import COMMIT, TAG, DATE
1 change: 1 addition & 0 deletions redo/version/_version.py.do
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
redo-ifchange vars
echo '"""Auto-generated file with git version information."""'
echo "# pylint: disable=bad-whitespace"
cat vars

0 comments on commit 29f9390

Please sign in to comment.