[PATCH 1/5] Accommodate and enable pylint no-member

0 views
Skip to first unread message

Rob Browning

unread,
Mar 14, 2026, 5:35:46 PM (10 days ago) Mar 14
to bup-...@googlegroups.com
For now, used @notimplemented more broadly as the indicator for
members of "abstract" classes that must be provided by subclasses.
Longer-term, perhaps restructure.

Signed-off-by: Rob Browning <r...@defaultvalue.org>
Tested-by: Rob Browning <r...@defaultvalue.org>
---
.pylintrc | 1 +
lib/bup/client.py | 4 ++++
lib/bup/cmd/save.py | 2 +-
lib/bup/cmd/split.py | 2 +-
lib/bup/git.py | 12 ++++++++++++
lib/bup/helpers.py | 7 +++++++
lib/bup/index.py | 3 +++
lib/bup/repo/base.py | 6 +-----
8 files changed, 30 insertions(+), 7 deletions(-)

diff --git a/.pylintrc b/.pylintrc
index 07ffc455..e875bcf2 100644
--- a/.pylintrc
+++ b/.pylintrc
@@ -47,6 +47,7 @@ enable=
no-else-continue,
no-else-raise,
no-else-return,
+ no-member,
no-value-for-parameter,
possibly-used-before-assignment,
raise-missing-from,
diff --git a/lib/bup/client.py b/lib/bup/client.py
index 1f8b261f..12ba3d6f 100644
--- a/lib/bup/client.py
+++ b/lib/bup/client.py
@@ -20,6 +20,7 @@ from bup.helpers import \
linereader,
lines_until_sentinel,
mkdirp,
+ notimplemented,
nullcontext_if_not,
progress,
qprogress,
@@ -74,6 +75,9 @@ class _AbstractTypicalCall:
raise extp(*ok_ex.args)
raise ok_ex

+ @notimplemented
+ def _check_ok(self): pass
+
class _TypicalCall(_AbstractTypicalCall):
def _check_ok(self):
# If this raises then protocol is out of sync, i.e. we should
diff --git a/lib/bup/cmd/save.py b/lib/bup/cmd/save.py
index 9ad87184..25112bbf 100644
--- a/lib/bup/cmd/save.py
+++ b/lib/bup/cmd/save.py
@@ -85,7 +85,7 @@ def opts_from_cmdline(o, argv):
try:
opt.date = parse_date_arg(b'--date', opt.date)
except ValueError as ex:
- o.fatal(ex.message)
+ o.fatal(str(ex))
else:
opt.date = time.time()

diff --git a/lib/bup/cmd/split.py b/lib/bup/cmd/split.py
index 0358ffc1..55fc6619 100644
--- a/lib/bup/cmd/split.py
+++ b/lib/bup/cmd/split.py
@@ -88,7 +88,7 @@ def opts_from_cmdline(o, argv):
try:
opt.date = parse_date_arg(b'--date', opt.date)
except ValueError as ex:
- o.fatal(ex.message)
+ o.fatal(str(ex))
else:
opt.date = time.time()

diff --git a/lib/bup/git.py b/lib/bup/git.py
index 3ecba804..01918f2f 100644
--- a/lib/bup/git.py
+++ b/lib/bup/git.py
@@ -28,6 +28,7 @@ from bup.helpers import (EXIT_FAILURE,
make_repo_id,
merge_iter,
mmap_read, mmap_readwrite,
+ notimplemented,
nullcontext_if_not,
progress, qprogress,
stopped,
@@ -345,6 +346,17 @@ def _decode_packobj(buf):


class PackIdx:
+
+ def __init__(self):
+ self.name = None
+ self.fanout = b''
+
+ @notimplemented
+ def _ofs_from_idx(self, idx): pass
+
+ @notimplemented
+ def _idx_to_hash(self, idx): pass
+
def find_offset(self, hash):
"""Get the offset of an object inside the index file."""
idx = self._idx_from_hash(hash)
diff --git a/lib/bup/helpers.py b/lib/bup/helpers.py
index 4e566a35..e2077c69 100644
--- a/lib/bup/helpers.py
+++ b/lib/bup/helpers.py
@@ -22,6 +22,12 @@ from bup.io import istty1, istty2, progress, qprogress, reprogress
from bup.options import _tty_width as tty_width


+def notimplemented(fn):
+ def newfn(obj, *args, **kwargs):
+ raise NotImplementedError(f'{obj.__class__.__name__}.{fn.__name__}')
+ return newfn
+
+
# EXIT_TRUE (just an alias) and EXIT_FALSE are intended for cases like
# POSIX grep or test, or bup's own "fsck --par2-ok", where the command
# is asking a question with a yes or no answer. Eventually all
@@ -177,6 +183,7 @@ else:
def _fullsync(fd):
try:
# Ignore result - errors will throw, other values undocumented
+ # pylint: disable=no-member
fcntl.fcntl(fd, fcntl.F_FULLFSYNC)
return True
except IOError as e:
diff --git a/lib/bup/index.py b/lib/bup/index.py
index 948178e3..3618862d 100644
--- a/lib/bup/index.py
+++ b/lib/bup/index.py
@@ -179,6 +179,9 @@ def _golevel(level, f, ename, newentry, metastore, tmax):


class Entry:
+ # The possible, pending index overhaul will obviate this, regardless.
+ # pylint: disable=no-member
+
def __init__(self, basename, name, meta_ofs, tmax):
assert basename is None or isinstance(basename, bytes)
assert name is None or isinstance(name, bytes)
diff --git a/lib/bup/repo/base.py b/lib/bup/repo/base.py
index 1849f33b..bfe49972 100644
--- a/lib/bup/repo/base.py
+++ b/lib/bup/repo/base.py
@@ -1,5 +1,6 @@

from bup.compat import dataclass
+from bup.helpers import notimplemented


def _make_base(config_get, compression_level, max_pack_size, max_pack_objects):
@@ -21,11 +22,6 @@ def _make_base(config_get, compression_level, max_pack_size, max_pack_objects):
max_pack_size=max_pack_size or config_get(b'pack.packSizeLimit',
opttype='int'))

-def notimplemented(fn):
- def newfn(obj, *args, **kwargs):
- raise NotImplementedError(f'{obj.__class__.__name__}.{fn.__name__}')
- return newfn
-
class RepoProtocol:
# Specification only; intentially has no implementations
# Subclassing just indicates intent.
--
2.47.3

Reply all
Reply to author
Forward
0 new messages