classification
Title: shutil.make_archive() root_dir do not work
Type: behavior Stage: needs patch
Components: Documentation, Library (Lib) Versions: Python 3.6, Python 3.5
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: docs@python Nosy List: DemoHT, bananaappletw, berker.peksag, docs@python, ezio.melotti, hynek, martin.panter, r.david.murray, rixx, serhiy.storchaka, tarek
Priority: normal Keywords: easy, patch

Created on 2014-07-21 09:50 by DemoHT, last changed 2018-05-30 12:35 by r.david.murray.

Files
File name Uploaded Description Edit
Issue22021.patch DemoHT, 2014-07-22 03:14 review
Messages (18)
msg223568 - (view) Author: Weinan Li (DemoHT) * Date: 2014-07-21 09:50
set root_dir do not work

output:
=====================================================
Python 3.4.0 (v3.4.0:04f714765c13, Mar 16 2014, 19:25:23) [MSC v.1600 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import shutil
>>> shutil.make_archive("tmp.tar.gz", "gztar", "c:/xjtu", "c:/tmp")
'C:\\Python34\\tmp.tar.gz.tar.gz'
=====================================================

source code of make_archive()
=====================================================
756    save_cwd = os.getcwd()
757    if root_dir is not None:
758        if logger is not None:
759            logger.debug("changing into '%s'", root_dir)
760        base_name = os.path.abspath(base_name)
761        if not dry_run:
762            os.chdir(root_dir)
...
...
782    try:
783        filename = func(base_name, base_dir, **kwargs)
784    finally:
=====================================================

base_name is set before chdir, so the archive always be created in cwd, whether set root_dir or not.
so, line 760 should be move below line 762
msg223569 - (view) Author: Ezio Melotti (ezio.melotti) * (Python committer) Date: 2014-07-21 09:58
Thanks for the report, do you want to provide a patch?
(You can check the devguide if you need more information.)
msg223572 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2014-07-21 11:04
I believe this is working as designed, although the documentation does not make that clear.  root dir is the root directory of the *created archive*, it has nothing to do with where the archive file itself is placed.
msg223622 - (view) Author: Weinan Li (DemoHT) * Date: 2014-07-22 02:06
I don't think so.

In source code, it just change work dir to root_dir, do nothing, and then the change word dir back.

If it works as design, the "root_dir" will be meaningless. should be remove.
msg223624 - (view) Author: Weinan Li (DemoHT) * Date: 2014-07-22 03:14
Here's the path
msg223668 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2014-07-22 12:11
The point *should* be that if you have something like:

   /home/me/some/directory/my/stuff/a
   /home/me/some/directory/my/stuff/b
   /home/me/some/other/directory

and you set rootdir to '/home/me/some' and base_dir='/home/me/some/directory/my' then the file paths in the archive will be:

    directory/my/stuff/a
    directory/my/stuff/b

At least, that's how I read the docs, though as I said they are *not* clear.  (I can't otherwise imagine any reason to have the root_dir parameter, with that name.)

Is this not what happens?
msg223805 - (view) Author: Weinan Li (DemoHT) * Date: 2014-07-24 03:07
that sounds reasonable
msg273073 - (view) Author: Wei Bo Chen (bananaappletw) Date: 2016-08-19 03:35
Sorry to bother.

But This patch is still not accepted.

I still suffer this issue.

Is anyone willing to review this patch?

Thanks
msg273074 - (view) Author: Wei Bo Chen (bananaappletw) Date: 2016-08-19 03:53
Or, Is there anything I could help?

I am glad to help fixing this issue.
msg273077 - (view) Author: Berker Peksag (berker.peksag) * (Python committer) Date: 2016-08-19 04:47
Hi bananaapple, there are two things that need to be addressed:

1. We need to decide whether this is a bug in make_archive() implementation or not. See msg223572 and msg223668 for details. I personally agree with David's analysis in msg223668.

We can rephrase make_archive() documentation to clarify what root_dir exactly does.

2. If this is a bug in make_archive() implementation, we need to add a test case. You can take a look at Lib/test/test_shutil.py.
msg273078 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2016-08-19 05:02
Agree with David, this is working as designed (and matching the behavior of say "tar -C"). But the documentation is not clear if not confusing.
msg273080 - (view) Author: Wei Bo Chen (bananaappletw) Date: 2016-08-19 05:21
Hello Berker Peksag,

1. For now, I realize the comment of David.

This is not a bug of make_archive() implementation.

However, I think documentation is not clear to understand at the first time reading it.

Maybe it should be rephrased.

2. Actually, what I am looking in this function is able to output the archive to another directory rather than current directory.

But, this functionality is not provided.

I think this functionality will be useful if implemented.

What do you think about this?

Thank you for your explaination.
msg273128 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2016-08-19 14:50
"base_name is the name of the file to create, including the path".  So you should be able to specify the path to where you want it created.  If that doesn't work, that's a bug.
msg273180 - (view) Author: Wei Bo Chen (bananaappletw) Date: 2016-08-20 01:35
I am sorry.

I understand now.

Thank you.
msg318132 - (view) Author: Tobias Kunze (rixx) * Date: 2018-05-29 22:39
I'm similarly confused by this issue. If somebody can help me understand what's going on, I'll put my understanding into a documentation patch.

I have created this minimal example to demonstrate what I don't understand: I've created a directory structure within /tmp like this:

issue22021
└── root
    └── structure
        ├── content
        │   └── please_add.txt
        └── do_not_add.txt


Now I'd like to create a zip archive that contains the directories "structure" and "content", and the file "please_add.txt", but not the file "do_not_add.txt". My understanding of the documentation was that I'd have to do this:

>>> shutil.make_archive(base_name='/tmp/issue22021archive', format='zip', root_dir='/tmp/issue22021/root', base_dir='/tmp/issue22021/root/structure/content')

But on my system, the created file (/tmp/issue22021archive.zip) looks like this according to unzip -l:

Archive:  issue22021archive.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  2018-05-30 00:26   tmp/issue22021/root/structure/content/
        0  2018-05-30 00:26   tmp/issue22021/root/structure/content/please_add.txt
---------                     -------
        0                     2 files

This is consistent with my experience that created archives will always contain directories from / on, which is unexpected to me.

It appears this happens whenever base_dir and root_dir is set, but to my understanding the documentation does not warn against this.

I've confirmed this behaviour with Python 3.6.5 and Python 3.5.3, but I suspect that doesn't really matter, as it seems to be a documentation issue.
msg318148 - (view) Author: Wei Bo Chen (bananaappletw) Date: 2018-05-30 03:50
I think this snippet might help you.

shutil.make_archive(base_name='/tmp/issue22021archive', format='zip', root_dir='/tmp/issue22021/root/', base_dir='structure/content/')

unzip -l /tmp/issue22021archive.zip

Archive:  /tmp/issue22021archive.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  2018-05-30 11:14   structure/content/
        0  2018-05-30 11:02   structure/content/please_add.txt
---------                     -------
        0                     2 files
msg318172 - (view) Author: Tobias Kunze (rixx) * Date: 2018-05-30 11:45
Thank you, that's what I figured out later last evening. To my understanding, the docs don't give any indication that base_dir is supposed to be relative to root_dir, so I'd add this information, and maybe add a similar example to the one above, if that's appropriate?
msg318178 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2018-05-30 12:35
Sounds reasonable to me.
History
Date User Action Args
2018-05-30 12:35:15r.david.murraysetmessages: + msg318178
2018-05-30 11:45:44rixxsetmessages: + msg318172
2018-05-30 03:50:59bananaappletwsetmessages: + msg318148
2018-05-29 22:39:30rixxsetnosy: + rixx
messages: + msg318132
2016-08-20 01:35:27bananaappletwsetmessages: + msg273180
2016-08-19 14:50:34r.david.murraysetmessages: + msg273128
2016-08-19 05:21:08bananaappletwsetmessages: + msg273080
2016-08-19 05:17:29berker.peksagsetversions: + Python 3.5, Python 3.6, - Python 3.4
2016-08-19 05:02:11serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg273078
2016-08-19 04:47:52berker.peksagsetnosy: + berker.peksag
messages: + msg273077
2016-08-19 03:53:27bananaappletwsetmessages: + msg273074
2016-08-19 03:35:07bananaappletwsetnosy: + bananaappletw
messages: + msg273073
2014-07-24 03:07:59DemoHTsetmessages: + msg223805
2014-07-22 12:11:03r.david.murraysetmessages: + msg223668
2014-07-22 04:27:15martin.pantersetnosy: + martin.panter
2014-07-22 03:14:20DemoHTsetfiles: + Issue22021.patch
keywords: + patch
messages: + msg223624
2014-07-22 02:06:16DemoHTsetmessages: + msg223622
2014-07-21 11:04:26r.david.murraysetnosy: + r.david.murray, docs@python
messages: + msg223572

assignee: docs@python
components: + Documentation
2014-07-21 09:58:44ezio.melottisetnosy: + hynek, ezio.melotti, tarek
messages: + msg223569

keywords: + easy
stage: needs patch
2014-07-21 09:50:13DemoHTcreate