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

Bug #1850440 reported by Paolo Montrasio
22
This bug affects 4 people
Affects Status Importance Assigned to Milestone
Duplicity
Fix Released
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  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.