Ubuntu 19.10 TypeError: Can't mix strings and bytes in path components

Bug #1850440 reported by Paolo Montrasio on 2019-10-29
22
This bug affects 4 people
Affects Status Importance Assigned to Milestone
Duplicity
Medium
Unassigned

Bug Description

$ /usr/bin/duplicity --version
duplicity 0.8.04
$ /usr/bin/python3 --version
Python 3.7.5rc1
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 19.10
Release: 19.10
Codename: eoan

I got these errors running this command (I faked the user name and IP address in this report)

$ duplicity remove-all-but-n-full 1 --force rsync://me@1.2.3.4//home/me/backup
Local and Remote metadata are synchronized, no sync needed.
Last full backup date: Tue Oct 29 12:51:01 2019
Deleting backup chain at time:
Mon Oct 28 09:14:17 2019
Deleting complete signature chain Mon Oct 28 09:14:17 2019
Deleting complete signature chain Mon Oct 28 09:14:17 2019
Attempt 1 failed. TypeError: Can't mix strings and bytes in path components
Attempt 2 failed. TypeError: Can't mix strings and bytes in path components
Attempt 3 failed. TypeError: Can't mix strings and bytes in path components
Attempt 4 failed. TypeError: Can't mix strings and bytes in path components
^CCleanup of temporary directory /tmp/duplicity-fan8xdb5-tempdir failed - this is probably a bug.

The full backup was successful and so it was an incremental one yesterday, built on top of other backups performed from Ubuntu 16.04. I did a fresh install of 19.10.

I fixed it with this code:

$ diff -u rsyncbackend.py.dist rsyncbackend.py
--- rsyncbackend.py.dist 2019-10-29 14:20:20.530795055 +0100
+++ rsyncbackend.py 2019-10-29 14:16:34.222447675 +0100
@@ -144,9 +144,14 @@
         exclude, exclude_name = tempdir.default().mkstemp_file()
         to_delete = [exclude_name]
         for file in dont_delete_list:
+ file = file.decode("utf-8")
             path = os.path.join(dir, file)
             to_delete.append(path)
- f = open(path, u'w')
+ try:
+ f = open(path, u'w')
+ except IsADirectoryError:
+ print(file, file=exclude)
+ continue
             print(file, file=exclude)
             f.close()
         exclude.close()
@@ -154,7 +159,10 @@
                        (self.cmd, exclude_name, dir, self.url_string))
         self.subprocess_popen(commandline)
         for file in to_delete:
- util.ignore_missing(os.unlink, file)
+ try:
+ util.ignore_missing(os.unlink, file)
+ except IsADirectoryError:
+ pass
         os.rmdir(dir)
```

The problem was that file is bytes and dir is a string.

There could be more than that because after fixing that at the beginning of the patch I run into other problems as both open and util.ignore_missing get directories as arguments. It's always "."

Example:

  File "/usr/lib/python3/dist-packages/duplicity/backends/rsyncbackend.py", line 150, in _delete_list
    f = open(path, u'w')
IsADirectoryError: [Errno 21] Is a directory: '/tmp/tmpa69qcojk/.'

This could be a separate bug but I'm in no position to assess that. If you want I'll open a second bug report for it.

Changed in duplicity:
importance: Undecided → Medium
milestone: none → 0.8.07
status: New → Fix Released
Changed in duplicity:
status: Fix Released → Fix Committed
Changed in duplicity:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers