Re: Duplicity 3.1.0 Released
Scott Hannahs via Duplicity-talk <[email protected]> Mon, 6 Jul 2026 15:03:43 -0400
| Newsgroups | gmane.comp.sysutils.backup.duplicity.general |
|---|---|
| Message-ID | <[email protected]> |
--===============6120608041777542328==
Content-Type: multipart/alternative;
boundary="Apple-Mail=_16C838E8-482A-4ADD-8069-58808FA69901"
--Apple-Mail=_16C838E8-482A-4ADD-8069-58808FA69901
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
charset=utf-8
I have and severely changed my requirements since the last update. But =
I have a few questions.
1. what are the non-python requirements? I have the following in =
previous versions, and I am sure that the gnupg2 is needed.
librsync2-shlibs (>=3D 2.0),
librsync-bin (>=3D 2.0),
gnupg2,
intltool40,
par2,
2. to support ftp backups and other non-python backends I had these were =
also required?
ncftp,
lftp,
Are these also no longer part of the duplicity backends? The =
requirements.txt and requirements.dev seem limited.
-Scott
> On Jun 28, 2026, at 2:29=E2=80=AFPM, Kenneth Loafman via =
Duplicity-talk <[email protected]> wrote:
>=20
> Hi Scott.
>=20
> 1. and 2. run fine with pylint=3D=3D4.0.5, black=3D=3D26.31
>=20
> 3. I really do not know why it is failing.
>=20
> Take a look at requirements.dev <http://requirements.dev/> and =
requirements.txt. You might want to do:
>=20
> $ python3 -m pip install --update -r requirements.dev =
<http://requirements.dev/>
> $ python3 -m pip install --update -r requirements.txt
> $ python3 -m pip install . # while in the duplicity directory
> =20
> as this will guarantee we're using the same environment. At least you =
can figure out what versions you need.
>=20
> ...Ken
>=20
>=20
> On Fri, Jun 26, 2026 at 10:53=E2=80=AFAM Scott Hannahs via =
Duplicity-talk <[email protected] =
<mailto:[email protected]>> wrote:
>> Thanks for the update. Trying to adjust my fink-project build system =
for this. I get a couple of failures when running the suite of tests. =
I know the pylint and the black tests are not necessary but I dislike =
failures in my output. Put it down to programmer OCD. I am sure the =
tests all passed on your system before you released it, but I am curious =
what is different on my system that all but these 3 tests would pass. I =
am using python 3.10 and pylint 2.14.5. Now updating pylint (and =
astroid) to current version.
>>=20
>> 1. pylint fails. It seems that building in a deep directory =
hierarchy causes python to abbreviate the strings with a =E2=80=98=E2=80=A6=
=E2=80=99 ellipsis. This of course causes all sorts of failures when =
the command line is called:
>> pylint =
--rcfile=3D/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/py=
project.toml /opt/sw/src/fink.b...l.3.1.0/duplicity/backend.py =
/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/duplicity/con=
fig.py
>>=20
>> The underlined text should be =
'/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/=E2=80=98 but even =
when using the full correct path, pylint gives me this error in the toml =
file. I assume that the paths are abbreviated just for error logging =
and the code is using the full paths?
>> pyproject.toml:1: [W0012(unknown-option-value), ] Unknown option =
value for '--disable', expected a valid pylint message and got =
'possibly-used-before-assignment=E2=80=99
>>=20
>> Standard error output:
>> ----------------------------- Captured stderr call =
-----------------------------
>> ************* Module =
/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/pyproject.tom=
l
>> =
/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/pyproject.tom=
l:1: [W0012(unknown-option-value), ] Unknown option value for =
'--disable', expected a valid pylint message and got =
'possibly-used-before-assignment'
>> ************* Module duplicity.statistics
>> =
/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/duplicity/sta=
tistics.py:154: [E1307(bad-string-format-type), =
StatsObj.get_timestats_string] Argument 'builtins.NoneType' does not =
match format type 'f'
>> =
/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/duplicity/sta=
tistics.py:162: [E1307(bad-string-format-type), =
StatsObj.get_timestats_string] Argument 'builtins.NoneType' does not =
match format type 'f'
>> ************* Module duplicity.backends.gdrivebackend
>> =
/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/duplicity/bac=
kends/gdrivebackend.py:102: [E0401(import-error), =
GDriveBackend.__init__] Unable to import 'google_auth_oauthlib.flow'
>> =
/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/duplicity/bac=
kends/gdrivebackend.py:103: [E0401(import-error), =
GDriveBackend.__init__] Unable to import =
'google.auth.transport.requests'
>> =
/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/duplicity/bac=
kends/gdrivebackend.py:217: [E0401(import-error), =
GDriveBackend.file_by_name] Unable to import 'googleapiclient.errors'
>> =
/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/duplicity/bac=
kends/gdrivebackend.py:286: [E0401(import-error), GDriveBackend._put] =
Unable to import 'googleapiclient.http'
>> =
/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/duplicity/bac=
kends/gdrivebackend.py:335: [E0401(import-error), GDriveBackend._get] =
Unable to import 'googleapiclient.http'
>> =
/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/duplicity/bac=
kends/gdrivebackend.py:402: [E0401(import-error), =
GDriveBackend._error_code] Unable to import 'google.auth.exceptions'
>> =
/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/duplicity/bac=
kends/gdrivebackend.py:403: [E0401(import-error), =
GDriveBackend._error_code] Unable to import 'googleapiclient.errors'
>> ************* Module duplicity.backends.pydrivebackend
>> =
/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/duplicity/bac=
kends/pydrivebackend.py:279: [E0401(import-error), =
PyDriveBackend._error_code] Unable to import 'pydrive2.files'
>> ************* Module duplicity.backends.azurebackend
>> =
/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/duplicity/bac=
kends/azurebackend.py:86: [E0401(import-error), =
AzureBackend._get_or_create_container] Unable to import =
'azure.core.exceptions'
>>=20
>>=20
>> 2. black fails too, probably for the same reason and I will try to =
fix it if I can get a resolution to the pylint issue.
>>=20
>> 3. This is further on a specific test for a code regression number =
908. I am including the long log here because I am not sure what is =
relevant.
>>=20
>> testing/functional/test_regression.py::RegressionTest::test_issue908 =
FAILED [ 72%]
>> =E2=80=94=E2=80=94
>> _________________________ RegressionTest.test_issue908 =
_________________________
>>=20
>> self =3D <testing.functional.test_regression.RegressionTest =
testMethod=3Dtest_issue908>
>>=20
>> @unittest.skipIf(os.path.exists("/.dockerenv"), "Won't work on =
docker")
>> def test_issue908(self):
>> """
>> Test issue 908 - gpg: public key decryption failed: No =
passphrase given (3.0.6.2)
>> """
>> =20
>> # make sure we test with a clean cache and clean output
>> self.set_environ("FTP_PASSWORD", None)
>> self.set_environ("PASSPHRASE", None)
>> self.set_environ("SIGN_PASSPHRASE", None)
>> self.set_environ("TESTDEBUG", None)
>> shutil.rmtree(f"{_runtest_dir}/testfiles/cache/issue908", =
ignore_errors=3DTrue)
>> shutil.rmtree(f"{_runtest_dir}/testfiles/output", =
ignore_errors=3DTrue)
>> =20
>> # do initial full backup with passphrase
>> self.backup(
>> "full",
>> f"{_runtest_dir}/testfiles/various_file_types",
>> options=3D["--name=3Dissue908", =
f"--encrypt-key=3D{self.encrypt_key1}"],
>> )
>> =20
>> # make sure inc has somthing to do
>> =
os.unlink(f"{_runtest_dir}/testfiles/various_file_types/executable")
>> =20
>> # do incremental backup
>> > self.backup(
>> "inc",
>> f"{_runtest_dir}/testfiles/various_file_types",
>> options=3D["--name=3Dissue908", =
f"--encrypt-key=3D{self.encrypt_key1}"],
>> passphrase_input=3D[self.sign_passphrase],
>> )
>>=20
>> self =3D <testing.functional.test_regression.RegressionTest =
testMethod=3Dtest_issue908>
>>=20
>> =
/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/testing/funct=
ional/test_regression.py:154:=20
>> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ =
_ _ _ _ _=20
>> =
/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/testing/funct=
ional/__init__.py:197: in backup
>> self.run_duplicity(options=3Doptions, **kwargs)
>> before_files =3D =
{b'duplicity-full-signatures.20260616T174134Z.sigtar.gpg', =
b'duplicity-full.20260616T174134Z.manifest.gpg', =
b'duplicity-full.20260616T174134Z.vol1.difftar.gpg'}
>> input_dir =3D =
'/var/folders/6b/85yg9bp94rv55dzbdp78thp40000kr/T/testfiles/various_file_t=
ypes'
>> kwargs =3D {'passphrase_input': ['test']}
>> now =3D 1781631694.437021
>> options =3D ['inc', =
'/var/folders/6b/85yg9bp94rv55dzbdp78thp40000kr/T/testfiles/various_file_t=
ypes', =
'fortestsonly:///var/folders/6b/85yg9bp94rv55dzbdp78thp40000kr/T/testfiles=
/output', '--volsize=3D1', '--name=3Dissue908', =
'--encrypt-key=3D839E6A2856538CCF']
>> self =3D =
<testing.functional.test_regression.RegressionTest =
testMethod=3Dtest_issue908>
>> type =3D 'inc'
>> =
/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/testing/funct=
ional/__init__.py:159: in run_duplicity
>> child.expect("passphrase.*:")
>> child =3D <pexpect.pty_spawn.spawn object at =
0x10abc27a0>
>> cmd_list =3D ['/opt/sw/bin/python3.10', '-W', 'ignore', =
'-u', =
'/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/duplicity/__=
main__.py', 'inc', ...]
>> cmdline =3D "'/opt/sw/bin/python3.10' '-W' 'ignore' '-u' =
'/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/duplicity/_.=
..538CCF' '-v0' '--no-print-statistics' =
'--archive-dir=3D/var/folders/6b/85yg9bp94rv55dzbdp78thp40000kr/T/testfile=
s/cache'"
>> current_time =3D None
>> dup_env =3D {'CCACHE_DIR': '/opt/sw/var/ccache', =
'CPPFLAGS': '-I/opt/sw/include', 'DBUS_SESSION_BUS_ADDRESS': =
'launchd:env=3DDBUS_FINK_SESSION_BUS_SOCKET', 'GNUPGHOME': =
'/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/testing/gnup=
g', ...}
>> fail =3D None
>> item =3D 'test'
>> options =3D ['inc', =
'/var/folders/6b/85yg9bp94rv55dzbdp78thp40000kr/T/testfiles/various_file_t=
ypes', =
'fortestsonly:///var/folders/6b/85yg9bp94rv55dzbdp78thp40000kr/T/testfiles=
/output', '--volsize=3D1', '--name=3Dissue908', =
'--encrypt-key=3D839E6A2856538CCF']
>> passphrase =3D 'test'
>> passphrase_input =3D ['test']
>> self =3D =
<testing.functional.test_regression.RegressionTest =
testMethod=3Dtest_issue908>
>> timeout =3D None
>> /opt/sw/lib/python3.10/site-packages/pexpect/spawnbase.py:343: in =
expect
>> return self.expect_list(compiled_pattern_list,
>> async_ =3D False
>> compiled_pattern_list =3D [re.compile(b'passphrase.*:', =
re.DOTALL)]
>> kw =3D {}
>> pattern =3D 'passphrase.*:'
>> searchwindowsize =3D -1
>> self =3D <pexpect.pty_spawn.spawn object at =
0x10abc27a0>
>> timeout =3D -1
>> /opt/sw/lib/python3.10/site-packages/pexpect/spawnbase.py:372: in =
expect_list
>> return exp.expect_loop(timeout)
>> async_ =3D False
>> exp =3D <pexpect.expect.Expecter object at =
0x109e4ff40>
>> kw =3D {}
>> pattern_list =3D [re.compile(b'passphrase.*:', re.DOTALL)]
>> searchwindowsize =3D -1
>> self =3D <pexpect.pty_spawn.spawn object at =
0x10abc27a0>
>> timeout =3D None
>> /opt/sw/lib/python3.10/site-packages/pexpect/expect.py:179: in =
expect_loop
>> return self.eof(e)
>> idx =3D None
>> self =3D <pexpect.expect.Expecter object at =
0x109e4ff40>
>> spawn =3D <pexpect.pty_spawn.spawn object at =
0x10abc27a0>
>> timeout =3D None
>> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ =
_ _ _ _ _=20
>>=20
>> self =3D <pexpect.expect.Expecter object at 0x109e4ff40>
>> err =3D EOF('End Of File (EOF). Empty string style platform.')
>>=20
>> def eof(self, err=3DNone):
>> spawn =3D self.spawn
>> =20
>> spawn.before =3D spawn._before.getvalue()
>> spawn._buffer =3D spawn.buffer_type()
>> spawn._before =3D spawn.buffer_type()
>> spawn.after =3D EOF
>> index =3D self.searcher.eof_index
>> if index >=3D 0:
>> spawn.match =3D EOF
>> spawn.match_index =3D index
>> return index
>> else:
>> spawn.match =3D None
>> spawn.match_index =3D None
>> msg =3D str(spawn)
>> msg +=3D '\nsearcher: %s' % self.searcher
>> if err is not None:
>> msg =3D str(err) + '\n' + msg
>> =20
>> exc =3D EOF(msg)
>> exc.__cause__ =3D None # in Python 3.x we can use "raise =
exc from None"
>> > raise exc
>> E pexpect.exceptions.EOF: End Of File (EOF). Empty string =
style platform.
>> E <pexpect.pty_spawn.spawn object at 0x10abc27a0>
>> E command: /bin/sh
>> E args: ['/bin/sh', '-f', '-c', "'/opt/sw/bin/python3.10' =
'-W' 'ignore' '-u' =
'/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/duplicity/__=
main__.py' 'inc' =
'/var/folders/6b/85yg9bp94rv55dzbdp78thp40000kr/T/testfiles/various_file_t=
ypes' =
'fortestsonly:///var/folders/6b/85yg9bp94rv55dzbdp78thp40000kr/T/testfiles=
/output' '--volsize=3D1' '--name=3Dissue908' =
'--encrypt-key=3D839E6A2856538CCF' '-v0' '--no-print-statistics' =
'--archive-dir=3D/var/folders/6b/85yg9bp94rv55dzbdp78thp40000kr/T/testfile=
s/cache'"]
>> E buffer (last 100 chars): b''
>> E before (last 100 chars): ''
>> E after: <class 'pexpect.exceptions.EOF'>
>> E match: None
>> E match_index: None
>> E exitstatus: None
>> E flag_eof: True
>> E pid: 45404
>> E child_fd: 191
>> E closed: False
>> E timeout: None
>> E delimiter: <class 'pexpect.exceptions.EOF'>
>> E logfile: None
>> E logfile_read: None
>> E logfile_send: None
>> E maxread: 2000
>> E ignorecase: False
>> E searchwindowsize: None
>> E delaybeforesend: 0.05
>> E delayafterclose: 0.1
>> E delayafterterminate: 0.1
>> E searcher: searcher_re:
>> E 0: re.compile(b'passphrase.*:')
>>=20
>> err =3D EOF('End Of File (EOF). Empty string style platform.')
>> exc =3D EOF('End Of File (EOF). Empty string style =
platform.\n<pexpect.pty_spawn.spawn object at 0x10abc27a0>\ncommand: =
/bin/s...: 0.05\ndelayafterclose: 0.1\ndelayafterterminate: =
0.1\nsearcher: searcher_re:\n 0: re.compile(b\'passphrase.*:\')')
>> index =3D -1
>> msg =3D "End Of File (EOF). Empty string style =
platform.\n<pexpect.pty_spawn.spawn object at 0x10abc27a0>\ncommand: =
/bin/sh\na...end: 0.05\ndelayafterclose: 0.1\ndelayafterterminate: =
0.1\nsearcher: searcher_re:\n 0: re.compile(b'passphrase.*:')"
>> self =3D <pexpect.expect.Expecter object at 0x109e4ff40>
>> spawn =3D <pexpect.pty_spawn.spawn object at 0x10abc27a0>
>>=20
>> /opt/sw/lib/python3.10/site-packages/pexpect/expect.py:122: EOF
>> ----------------------------- Captured stdout call =
-----------------------------
>> TestBackend is not made for production use!
>> TestBackend is not made for production use!
>> TestBackend is not made for production use!
>> TestBackend is not made for production use!
>> ----------------------------- Captured stderr call =
-----------------------------
>>=20
>> ...command: '/opt/sw/bin/python3.10' '-W' 'ignore' '-u' =
'/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/duplicity/__=
main__.py' 'full' =
'/var/folders/6b/85yg9bp94rv55dzbdp78thp40000kr/T/testfiles/various_file_t=
ypes' =
'fortestsonly:///var/folders/6b/85yg9bp94rv55dzbdp78thp40000kr/T/testfiles=
/output' '--volsize=3D1' '--name=3Dissue908' =
'--encrypt-key=3D839E6A2856538CCF' '-v0' '--no-print-statistics' =
'--archive-dir=3D/var/folders/6b/85yg9bp94rv55dzbdp78thp40000kr/T/testfile=
s/cache' < /dev/null
>> ...cwd: /private/var/folders/6b/85yg9bp94rv55dzbdp78thp40000kr/T
>> ...output:
>> ...return_val: 0
>> ------------------------------ Captured log call =
-------------------------------
>> Level 8 duplicity:log.py:100 TestBackend is not made for production =
use!
>> Level 8 duplicity:log.py:100 TestBackend is not made for production =
use!
>> Level 8 duplicity:log.py:100 TestBackend is not made for production =
use!
>> Level 8 duplicity:log.py:100 TestBackend is not made for production =
use!
>> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D short test summary info =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
>> -Scott
>>=20
>>> On Jun 16, 2026, at 1:10=E2=80=AFPM, Kenneth Loafman via =
Duplicity-talk <[email protected] =
<mailto:[email protected]>> wrote:
>>>=20
>>> Hi everyone,
>>>=20
>>> I am pleased to announce the release of duplicity version 3.1.0.
>>>=20
>>> This release follows version 3.0.7 and includes a minor version bump =
to reflect a significant new feature. Thanks to elmuz's contribution, =
restore operations can now use --include, --exclude, --include-regexp, =
and --include-filelist directly from the command line.
>>>=20
>>> There are many other improvements and bug fixes included in this =
update. Please see the CHANGELOG below for full details.
>>>=20
>>> Thanks,
>>> Ken
>>=20
>> _______________________________________________
>> Duplicity-talk mailing list
>> [email protected] <mailto:[email protected]>
>> https://lists.nongnu.org/mailman/listinfo/duplicity-talk
> _______________________________________________
> Duplicity-talk mailing list
> [email protected]
> https://lists.nongnu.org/mailman/listinfo/duplicity-talk
--Apple-Mail=_16C838E8-482A-4ADD-8069-58808FA69901
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html;
charset=utf-8
<html aria-label=3D"message body"><head><meta http-equiv=3D"content-type" =
content=3D"text/html; charset=3Dutf-8"></head><body =
style=3D"overflow-wrap: break-word; -webkit-nbsp-mode: space; =
line-break: after-white-space;">I have and severely changed my =
requirements since the last update. But I have a few =
questions.<div><br></div><div>1. what are the non-python requirements? =
I have the following in previous versions, and I am sure that the =
gnupg2 is needed.</div><div><div> =
librsync2-shlibs (>=3D 2.0),</div><div> =
librsync-bin (>=3D 2.0),</div><div> =
gnupg2,</div><div> =
intltool40,</div><div><span class=3D"Apple-tab-span" =
style=3D"white-space:pre"> =
</span>par2,</div><div><br></div><div><br></div><div>2. to support ftp =
backups and other non-python backends I had these were also =
required?</div><div><div> =
ncftp,</div><div> =
lftp,</div><div><br></div></div><div>Are these also no longer part of =
the duplicity backends? The requirements.txt and requirements.dev =
seem =
limited.</div><div><br></div><div>-Scott</div><div><br></div><div><blockqu=
ote type=3D"cite"><div>On Jun 28, 2026, at 2:29=E2=80=AFPM, Kenneth =
Loafman via Duplicity-talk <[email protected]> =
wrote:</div><br class=3D"Apple-interchange-newline"><div><div =
dir=3D"ltr"><div dir=3D"ltr"><div>Hi Scott.</div><div><br></div><div>1. =
and 2. run fine with pylint=3D=3D4.0.5, =
black=3D=3D26.31</div><div><br></div><div>3. I really do not know why it =
is failing.</div><div><br></div><div>Take a look at <a =
href=3D"http://requirements.dev/">requirements.dev</a> and =
requirements.txt. You might want to =
do:</div><div><br></div><div><font face=3D"monospace" =
style=3D"background-color:rgb(238,238,238)">$ python3 -m pip install =
--update -r <a =
href=3D"http://requirements.dev/">requirements.dev</a></font></div><div><f=
ont face=3D"monospace" style=3D"background-color:rgb(238,238,238)">$ =
python3 -m pip install --update -r =
requirements.txt</font></div><div><font face=3D"monospace" =
style=3D"background-color:rgb(238,238,238)">$ python3 -m pip install =
. # while in the duplicity =
directory</font></div><div> </div><div>as this will guarantee we're =
using the same environment. At least you can figure out what =
versions you =
need.</div><div><br></div><div>...Ken</div><div><br></div><br><div =
class=3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_attr">On Fri, Jun =
26, 2026 at 10:53=E2=80=AFAM Scott Hannahs via Duplicity-talk <<a =
href=3D"mailto:[email protected]" =
target=3D"_blank">[email protected]</a>> =
wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px =
0px 0px 0.8ex;border-left:1px solid =
rgb(204,204,204);padding-left:1ex"><div><div dir=3D"auto"><div =
dir=3D"auto"><div dir=3D"auto"><div dir=3D"auto">Thanks for the =
update. Trying to adjust my fink-project build system for =
this. I get a couple of failures when running the suite of =
tests. I know the pylint and the black tests are not necessary but =
I dislike failures in my output. Put it down to programmer =
OCD. I am sure the tests all passed on your system before you =
released it, but I am curious what is different on my system that all =
but these 3 tests would pass. I am using python 3.10 and pylint =
2.14.5. Now updating pylint (and astroid) to current =
version.<div><br></div><div>1. pylint fails. It seems that =
building in a deep directory hierarchy causes python to abbreviate the =
strings with a =E2=80=98=E2=80=A6=E2=80=99 ellipsis. This of =
course causes all sorts of failures when the command line is =
called:</div><blockquote style=3D"margin:0px 0px 0px =
40px;border-width:medium;border-style:none;border-color:currentcolor;paddi=
ng:0px"><div>pylint =
--rcfile=3D/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/py=
project.toml /opt/sw/src/<b =
style=3D"font-size:16px"><u>fink.b...l.3.1.0</u></b>/duplicity/backend.py =
/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/duplicity/con=
fig.py</div></blockquote><div><div><br></div><div>The underlined text =
should be '/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/=E2=80=98 =
but even when using the full correct path, pylint gives me this error in =
the toml file. I assume that the paths are abbreviated just for =
error logging and the code is using the full =
paths?</div></div><blockquote style=3D"margin:0px 0px 0px =
40px;border-width:medium;border-style:none;border-color:currentcolor;paddi=
ng:0px"><div><div>pyproject.toml:1: [W0012(unknown-option-value), ] =
Unknown option value for '--disable', expected a valid pylint message =
and got =
'possibly-used-before-assignment=E2=80=99</div></div><div><br></div></bloc=
kquote><div>Standard error output:</div><blockquote style=3D"margin:0px =
0px 0px =
40px;border-width:medium;border-style:none;border-color:currentcolor;paddi=
ng:0px"><div><div>----------------------------- Captured stderr call =
-----------------------------</div><div>************* Module =
/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/pyproject.tom=
l</div><div =
style=3D"font-size:16px"><b>/opt/sw/src/fink.build/duplicity-3.1.0-1/dupli=
city-rel.3.1.0/pyproject.toml:1: [W0012(unknown-option-value), ] Unknown =
option value for '--disable', expected a valid pylint message and got =
'possibly-used-before-assignment'</b></div><div>************* Module =
duplicity.statistics</div><div>/opt/sw/src/fink.build/duplicity-3.1.0-1/du=
plicity-rel.3.1.0/duplicity/statistics.py:154: =
[E1307(bad-string-format-type), StatsObj.get_timestats_string] Argument =
'builtins.NoneType' does not match format type =
'f'</div><div>/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0=
/duplicity/statistics.py:162: [E1307(bad-string-format-type), =
StatsObj.get_timestats_string] Argument 'builtins.NoneType' does not =
match format type 'f'</div><div>************* Module =
duplicity.backends.gdrivebackend</div><div>/opt/sw/src/fink.build/duplicit=
y-3.1.0-1/duplicity-rel.3.1.0/duplicity/backends/gdrivebackend.py:102: =
[E0401(import-error), GDriveBackend.__init__] Unable to import =
'google_auth_oauthlib.flow'</div><div>/opt/sw/src/fink.build/duplicity-3.1=
.0-1/duplicity-rel.3.1.0/duplicity/backends/gdrivebackend.py:103: =
[E0401(import-error), GDriveBackend.__init__] Unable to import =
'google.auth.transport.requests'</div><div>/opt/sw/src/fink.build/duplicit=
y-3.1.0-1/duplicity-rel.3.1.0/duplicity/backends/gdrivebackend.py:217: =
[E0401(import-error), GDriveBackend.file_by_name] Unable to import =
'googleapiclient.errors'</div><div>/opt/sw/src/fink.build/duplicity-3.1.0-=
1/duplicity-rel.3.1.0/duplicity/backends/gdrivebackend.py:286: =
[E0401(import-error), GDriveBackend._put] Unable to import =
'googleapiclient.http'</div><div>/opt/sw/src/fink.build/duplicity-3.1.0-1/=
duplicity-rel.3.1.0/duplicity/backends/gdrivebackend.py:335: =
[E0401(import-error), GDriveBackend._get] Unable to import =
'googleapiclient.http'</div><div>/opt/sw/src/fink.build/duplicity-3.1.0-1/=
duplicity-rel.3.1.0/duplicity/backends/gdrivebackend.py:402: =
[E0401(import-error), GDriveBackend._error_code] Unable to import =
'google.auth.exceptions'</div><div>/opt/sw/src/fink.build/duplicity-3.1.0-=
1/duplicity-rel.3.1.0/duplicity/backends/gdrivebackend.py:403: =
[E0401(import-error), GDriveBackend._error_code] Unable to import =
'googleapiclient.errors'</div><div>************* Module =
duplicity.backends.pydrivebackend</div><div>/opt/sw/src/fink.build/duplici=
ty-3.1.0-1/duplicity-rel.3.1.0/duplicity/backends/pydrivebackend.py:279: =
[E0401(import-error), PyDriveBackend._error_code] Unable to import =
'pydrive2.files'</div><div>************* Module =
duplicity.backends.azurebackend</div><div>/opt/sw/src/fink.build/duplicity=
-3.1.0-1/duplicity-rel.3.1.0/duplicity/backends/azurebackend.py:86: =
[E0401(import-error), AzureBackend._get_or_create_container] Unable to =
import =
'azure.core.exceptions'</div><div><br></div></div></blockquote><div><div><=
br></div><div>2. black fails too, probably for the same reason and I =
will try to fix it if I can get a resolution to the pylint =
issue.</div><div><br></div><div>3. This is further on a specific test =
for a code regression number 908. I am including the long log here =
because I am not sure what is =
relevant.</div></div><div><br></div><blockquote style=3D"margin:0px 0px =
0px =
40px;border-width:medium;border-style:none;border-color:currentcolor;paddi=
ng:0px"><div><div>testing/functional/test_regression.py::RegressionTest::t=
est_issue908 FAILED [ =
72%]</div></div><div>=E2=80=94=E2=80=94</div><div><div>___________________=
______ RegressionTest.test_issue908 =
_________________________</div><div><br></div><div>self =3D =
<testing.functional.test_regression.RegressionTest =
testMethod=3Dtest_issue908></div><div><br></div><div> =
@unittest.skipIf(os.path.exists("/.dockerenv"), "Won't work on =
docker")</div><div> def =
test_issue908(self):</div><div> =
"""</div><div> Test issue 908 - gpg: public =
key decryption failed: No passphrase given (3.0.6.2)</div><div> =
"""</div><div> </div><div> =
# make sure we test with a clean cache and clean =
output</div><div> =
self.set_environ("FTP_PASSWORD", None)</div><div> =
self.set_environ("PASSPHRASE", None)</div><div> =
self.set_environ("SIGN_PASSPHRASE", None)</div><div> =
self.set_environ("TESTDEBUG", =
None)</div><div> =
shutil.rmtree(f"{_runtest_dir}/testfiles/cache/issue908", =
ignore_errors=3DTrue)</div><div> =
shutil.rmtree(f"{_runtest_dir}/testfiles/output", =
ignore_errors=3DTrue)</div><div> </div><div> =
# do initial full backup with =
passphrase</div><div> =
self.backup(</div><div> =
"full",</div><div> =
f"{_runtest_dir}/testfiles/various_file_types",</div><div> =
options=3D["--name=3Dissue908", =
f"--encrypt-key=3D{self.encrypt_key1}"],</div><div> =
)</div><div> </div><div> =
# make sure inc has somthing to do</div><div> =
=
os.unlink(f"{_runtest_dir}/testfiles/various_file_types/executable")</div>=
<div> </div><div> # do =
incremental backup</div><div>> =
self.backup(</div><div> =
"inc",</div><div> =
f"{_runtest_dir}/testfiles/various_file_types",</div><div> =
options=3D["--name=3Dissue908", =
f"--encrypt-key=3D{self.encrypt_key1}"],</div><div> =
=
passphrase_input=3D[self.sign_passphrase],</div><div> =
)</div><div><br></div><div>self =3D =
<testing.functional.test_regression.RegressionTest =
testMethod=3Dtest_issue908></div><div><br></div><div>/opt/sw/src/fink.b=
uild/duplicity-3.1.0-1/duplicity-rel.3.1.0/testing/functional/test_regress=
ion.py:154: </div><div>_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ =
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ =
_ </div><div><div>/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-=
rel.3.1.0/testing/functional/__init__.py:197: in backup</div><div> =
self.run_duplicity(options=3Doptions, **kwargs)</div><div> =
before_files =3D =
{b'duplicity-full-signatures.20260616T174134Z.sigtar.gpg', =
b'duplicity-full.20260616T174134Z.manifest.gpg', =
b'duplicity-full.20260616T174134Z.vol1.difftar.gpg'}</div><div> =
input_dir =3D =
'/var/folders/6b/85yg9bp94rv55dzbdp78thp40000kr/T/testfiles/various_file_t=
ypes'</div><div> kwargs =3D =
{'passphrase_input': ['test']}</div><div> now =
=3D 1781631694.437021</div><div> =
options =3D ['inc', =
'/var/folders/6b/85yg9bp94rv55dzbdp78thp40000kr/T/testfiles/various_file_t=
ypes', =
'fortestsonly:///var/folders/6b/85yg9bp94rv55dzbdp78thp40000kr/T/testfiles=
/output', '--volsize=3D1', '--name=3Dissue908', =
'--encrypt-key=3D839E6A2856538CCF']</div><div> =
self =3D =
<testing.functional.test_regression.RegressionTest =
testMethod=3Dtest_issue908></div><div> =
type =3D =
'inc'</div><div>/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1=
.0/testing/functional/__init__.py:159: in run_duplicity</div><div> =
child.expect("passphrase.*:")</div><div> =
child =3D <pexpect.pty_spawn.spawn object =
at 0x10abc27a0></div><div> cmd_list =
=3D ['/opt/sw/bin/python3.10', '-W', 'ignore', '-u', =
'/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/duplicity/__=
main__.py', 'inc', ...]</div><div> cmdline =
=3D "'/opt/sw/bin/python3.10' '-W' 'ignore' '-u' =
'/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/duplicity/_.=
..538CCF' '-v0' '--no-print-statistics' =
'--archive-dir=3D/var/folders/6b/85yg9bp94rv55dzbdp78thp40000kr/T/testfile=
s/cache'"</div><div> current_time =3D =
None</div><div> dup_env =3D =
{'CCACHE_DIR': '/opt/sw/var/ccache', 'CPPFLAGS': '-I/opt/sw/include', =
'DBUS_SESSION_BUS_ADDRESS': 'launchd:env=3DDBUS_FINK_SESSION_BUS_SOCKET', =
'GNUPGHOME': =
'/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/testing/gnup=
g', ...}</div><div> fail =
=3D None</div><div> item =
=3D 'test'</div><div> options =3D =
['inc', =
'/var/folders/6b/85yg9bp94rv55dzbdp78thp40000kr/T/testfiles/various_file_t=
ypes', =
'fortestsonly:///var/folders/6b/85yg9bp94rv55dzbdp78thp40000kr/T/testfiles=
/output', '--volsize=3D1', '--name=3Dissue908', =
'--encrypt-key=3D839E6A2856538CCF']</div><div> =
passphrase =3D 'test'</div><div> =
passphrase_input =3D ['test']</div><div> self =
=3D =
<testing.functional.test_regression.RegressionTest =
testMethod=3Dtest_issue908></div><div> =
timeout =3D =
None</div><div>/opt/sw/lib/python3.10/site-packages/pexpect/spawnbase.py:3=
43: in expect</div><div> return =
self.expect_list(compiled_pattern_list,</div><div> =
async_ =3D False</div><div> =
compiled_pattern_list =3D [re.compile(b'passphrase.*:', =
re.DOTALL)]</div><div> kw =
=3D {}</div><div> pattern =
=3D 'passphrase.*:'</div><div> =
searchwindowsize =3D -1</div><div> self =
=3D <pexpect.pty_spawn.spawn object at =
0x10abc27a0></div><div> timeout =
=3D =
-1</div><div>/opt/sw/lib/python3.10/site-packages/pexpect/spawnbase.py:372=
: in expect_list</div><div> return =
exp.expect_loop(timeout)</div><div> async_ =
=3D False</div><div> exp =
=3D <pexpect.expect.Expecter object at =
0x109e4ff40></div><div> kw =
=3D {}</div><div> pattern_list =
=3D [re.compile(b'passphrase.*:', re.DOTALL)]</div><div> =
searchwindowsize =3D -1</div><div> =
self =3D <pexpect.pty_spawn.spawn object =
at 0x10abc27a0></div><div> timeout =
=3D =
None</div><div>/opt/sw/lib/python3.10/site-packages/pexpect/expect.py:179:=
in expect_loop</div><div> return =
self.eof(e)</div><div> idx =
=3D None</div><div> self =
=3D <pexpect.expect.Expecter object at =
0x109e4ff40></div><div> spawn =
=3D <pexpect.pty_spawn.spawn object at =
0x10abc27a0></div><div> timeout =
=3D None</div><div>_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ =
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ </div><div><br></div><div>self =3D =
<pexpect.expect.Expecter object at 0x109e4ff40></div><div>err =3D =
EOF('End Of File (EOF). Empty string style =
platform.')</div><div><br></div><div> def eof(self, =
err=3DNone):</div><div> spawn =3D =
self.spawn</div><div> </div><div> =
spawn.before =3D spawn._before.getvalue()</div><div> =
spawn._buffer =3D spawn.buffer_type()</div><div> =
spawn._before =3D =
spawn.buffer_type()</div><div> spawn.after =3D =
EOF</div><div> index =3D =
self.searcher.eof_index</div><div> if index =
>=3D 0:</div><div> =
spawn.match =3D EOF</div><div> =
spawn.match_index =3D index</div><div> =
return index</div><div> =
else:</div><div> spawn.match =3D =
None</div><div> =
spawn.match_index =3D None</div><div> =
msg =3D str(spawn)</div><div> =
msg +=3D '\nsearcher: %s' % self.searcher</div><div> =
if err is not None:</div><div> =
msg =3D str(err) + '\n' + =
msg</div><div> </div><div> =
exc =3D EOF(msg)</div><div> =
exc.__cause__ =3D None # in Python 3.x we can use "raise =
exc from None"</div><div>> raise =
exc</div><div>E =
pexpect.exceptions.EOF: End Of File (EOF). Empty string style =
platform.</div><div>E =
<pexpect.pty_spawn.spawn object at 0x10abc27a0></div><div>E =
command: /bin/sh</div><div>E =
args: ['/bin/sh', '-f', '-c', =
"'/opt/sw/bin/python3.10' '-W' 'ignore' '-u' =
'/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/duplicity/__=
main__.py' 'inc' =
'/var/folders/6b/85yg9bp94rv55dzbdp78thp40000kr/T/testfiles/various_file_t=
ypes' =
'fortestsonly:///var/folders/6b/85yg9bp94rv55dzbdp78thp40000kr/T/testfiles=
/output' '--volsize=3D1' '--name=3Dissue908' =
'--encrypt-key=3D839E6A2856538CCF' '-v0' '--no-print-statistics' =
'--archive-dir=3D/var/folders/6b/85yg9bp94rv55dzbdp78thp40000kr/T/testfile=
s/cache'"]</div><div>E buffer (last =
100 chars): b''</div><div>E before =
(last 100 chars): ''</div><div>E =
after: <class 'pexpect.exceptions.EOF'></div><div>E =
match: None</div><div>E =
match_index: None</div><div>E =
exitstatus: None</div><div>E =
flag_eof: True</div><div>E pid: =
45404</div><div>E child_fd: =
191</div><div>E closed: =
False</div><div>E timeout: =
None</div><div>E delimiter: <class =
'pexpect.exceptions.EOF'></div><div>E =
logfile: None</div><div>E =
logfile_read: None</div><div>E =
logfile_send: None</div><div>E =
maxread: 2000</div><div>E ignorecase: =
False</div><div>E searchwindowsize: =
None</div><div>E delaybeforesend: =
0.05</div><div>E delayafterclose: =
0.1</div><div>E delayafterterminate: =
0.1</div><div>E searcher: =
searcher_re:</div><div>E =
0: re.compile(b'passphrase.*:')</div><div><br></div><div>err =
=3D EOF('End Of File (EOF). Empty string =
style platform.')</div><div>exc =3D EOF('End =
Of File (EOF). Empty string style platform.\n<pexpect.pty_spawn.spawn =
object at 0x10abc27a0>\ncommand: /bin/s...: 0.05\ndelayafterclose: =
0.1\ndelayafterterminate: 0.1\nsearcher: searcher_re:\n 0: =
re.compile(b\'passphrase.*:\')')</div><div>index =3D =
-1</div><div>msg =3D "End Of File (EOF). =
Empty string style platform.\n<pexpect.pty_spawn.spawn object at =
0x10abc27a0>\ncommand: /bin/sh\na...end: 0.05\ndelayafterclose: =
0.1\ndelayafterterminate: 0.1\nsearcher: searcher_re:\n 0: =
re.compile(b'passphrase.*:')"</div><div>self =3D =
<pexpect.expect.Expecter object at 0x109e4ff40></div><div>spawn =
=3D <pexpect.pty_spawn.spawn object at =
0x10abc27a0></div><div><br></div><div>/opt/sw/lib/python3.10/site-packa=
ges/pexpect/expect.py:122: EOF</div><div>----------------------------- =
Captured stdout call -----------------------------</div><div>TestBackend =
is not made for production use!</div><div>TestBackend is not made for =
production use!</div><div>TestBackend is not made for production =
use!</div><div>TestBackend is not made for production =
use!</div><div>----------------------------- Captured stderr call =
-----------------------------</div><div><br></div><div>...command: =
'/opt/sw/bin/python3.10' '-W' 'ignore' '-u' =
'/opt/sw/src/fink.build/duplicity-3.1.0-1/duplicity-rel.3.1.0/duplicity/__=
main__.py' 'full' =
'/var/folders/6b/85yg9bp94rv55dzbdp78thp40000kr/T/testfiles/various_file_t=
ypes' =
'fortestsonly:///var/folders/6b/85yg9bp94rv55dzbdp78thp40000kr/T/testfiles=
/output' '--volsize=3D1' '--name=3Dissue908' =
'--encrypt-key=3D839E6A2856538CCF' '-v0' '--no-print-statistics' =
'--archive-dir=3D/var/folders/6b/85yg9bp94rv55dzbdp78thp40000kr/T/testfile=
s/cache' < /dev/null</div><div>...cwd: =
/private/var/folders/6b/85yg9bp94rv55dzbdp78thp40000kr/T</div><div>...outp=
ut:</div><div>...return_val: 0</div><div>------------------------------ =
Captured log call -------------------------------</div><div>Level 8 =
duplicity:log.py:100 TestBackend is not made for production =
use!</div><div>Level 8 duplicity:log.py:100 TestBackend is not =
made for production use!</div><div>Level 8 duplicity:log.py:100 =
TestBackend is not made for production use!</div><div>Level 8 =
duplicity:log.py:100 TestBackend is not made for production =
use!</div><div>=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D short test summary info =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D</div></div></div></blockquote><div>-Scott</div><div><div><br><bl=
ockquote type=3D"cite"><div>On Jun 16, 2026, at 1:10=E2=80=AFPM, Kenneth =
Loafman via Duplicity-talk <<a =
href=3D"mailto:[email protected]" =
target=3D"_blank">[email protected]</a>> =
wrote:</div><br><div><div dir=3D"ltr">Hi everyone,<br><br>I am pleased =
to announce the release of duplicity version 3.1.0.<br><br>This release =
follows version 3.0.7 and includes a minor version bump to reflect a =
significant new feature. Thanks to elmuz's contribution, restore =
operations can now use --include, --exclude, --include-regexp, and =
--include-filelist directly from the command line.<br><br>There are many =
other improvements and bug fixes included in this update. Please see the =
CHANGELOG below for full =
details.<br><br>Thanks,<br>Ken<br></div></div></blockquote></div><br></div=
></div></div></div></div></div>___________________________________________=
____<br>
Duplicity-talk mailing list<br>
<a href=3D"mailto:[email protected]" =
target=3D"_blank">[email protected]</a><br>
<a href=3D"https://lists.nongnu.org/mailman/listinfo/duplicity-talk" =
rel=3D"noreferrer" =
target=3D"_blank">https://lists.nongnu.org/mailman/listinfo/duplicity-talk=
</a><br>
</blockquote></div></div>
</div>
_______________________________________________<br>Duplicity-talk =
mailing =
list<br>[email protected]<br>https://lists.nongnu.org/mailman/list=
info/duplicity-talk<br></div></blockquote></div><br></div></body></html>=
--Apple-Mail=_16C838E8-482A-4ADD-8069-58808FA69901--
--===============6120608041777542328==
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Content-Disposition: inline
X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KRHVwbGljaXR5
LXRhbGsgbWFpbGluZyBsaXN0CkR1cGxpY2l0eS10YWxrQG5vbmdudS5vcmcKaHR0cHM6Ly9saXN0
cy5ub25nbnUub3JnL21haWxtYW4vbGlzdGluZm8vZHVwbGljaXR5LXRhbGsK
--===============6120608041777542328==--