Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pathlib.Path unexpected (wrong) behaviour when combining paths in a for loop #80515

Closed
MikeDavies mannequin opened this issue Mar 18, 2019 · 2 comments
Closed

pathlib.Path unexpected (wrong) behaviour when combining paths in a for loop #80515

MikeDavies mannequin opened this issue Mar 18, 2019 · 2 comments
Labels
3.7 (EOL) end of life OS-windows type-bug An unexpected behavior, bug, or error

Comments

@MikeDavies
Copy link
Mannequin

MikeDavies mannequin commented Mar 18, 2019

BPO 36334
Nosy @pfmoore, @tjguk, @zware, @eryksun, @zooba

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = <Date 2019-03-18.04:08:02.973>
created_at = <Date 2019-03-18.02:12:20.452>
labels = ['invalid', 'type-bug', '3.7', 'OS-windows']
title = 'pathlib.Path  unexpected (wrong) behaviour when combining paths in a for loop'
updated_at = <Date 2019-03-18.04:08:02.971>
user = 'https://bugs.python.org/MikeDavies'

bugs.python.org fields:

activity = <Date 2019-03-18.04:08:02.971>
actor = 'eryksun'
assignee = 'none'
closed = True
closed_date = <Date 2019-03-18.04:08:02.973>
closer = 'eryksun'
components = ['Windows']
creation = <Date 2019-03-18.02:12:20.452>
creator = 'Mike Davies'
dependencies = []
files = []
hgrepos = []
issue_num = 36334
keywords = []
message_count = 2.0
messages = ['338156', '338160']
nosy_count = 6.0
nosy_names = ['paul.moore', 'tim.golden', 'zach.ware', 'eryksun', 'steve.dower', 'Mike Davies']
pr_nums = []
priority = 'normal'
resolution = 'not a bug'
stage = 'resolved'
status = 'closed'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue36334'
versions = ['Python 3.7']

@MikeDavies
Copy link
Mannequin Author

MikeDavies mannequin commented Mar 18, 2019

I wish to create a list of pathlib.Paths by combining two lists of pathlib.Paths. I use two for loops to make every combination.

However the output is not what one would expect (see no 'Program Files' is visible in the output).

########## INPUT:
pa = [   
    Path('C:/Program Files'),
    Path('C:/')
]
pb = [
    Path('/one/two/three.exe'),
    Path('/four.exe') 
    ]
print( [a/b for a in pa for b in pb] )

########### OUTPUT:
[WindowsPath('C:/one/two/three.exe'), WindowsPath('C:/four.exe'), WindowsPath('C:/one/two/three.exe'), WindowsPath('C:/four.exe')]

This is true whether I use for loops or list comprehensions.

To get the expected output I need to change the Paths to strings, combine them, then convert them back to paths like this:

########### INPUT:
print( [Path(str(a)+str(b)) for a in pa for b in pb] )
########### OUTPUT:
[WindowsPath('C:/Program Files/one/two/three.exe'), WindowsPath('C:/Program Files/four.exe'), WindowsPath('C:/one/two/three.exe'), WindowsPath('C:/four.exe')]

Interestingly if I print only 'a' I get the expected answer:
########### INPUT:
print( [a for a in pa for b in pb] )
########### OUTPUT:
[WindowsPath('C:/Program Files'), WindowsPath('C:/Program Files'), WindowsPath('C:/'), WindowsPath('C:/')]

And the same is true if I print only 'b':
########### INPUT:
print( [b for a in pa for b in pb] )
########### OUTPUT:
[WindowsPath('/one/two/three.exe'), WindowsPath('/four.exe'), WindowsPath('/one/two/three.exe'), WindowsPath('/four.exe')]

Additionally in some cases it does give the correct answer. Here is a similar example where the answer is correct:
########### INPUT:
pa = [Path('C:/'), Path('D:/')]
pb = [Path('a.exe'), Path('b.exe')]
print( [a/b for a in pa for b in pb] )
########### OUTPUT:
[WindowsPath('C:/a.exe'), WindowsPath('C:/b.exe'), WindowsPath('D:/a.exe'), WindowsPath('D:/b.exe')]

@MikeDavies MikeDavies mannequin added 3.7 (EOL) end of life OS-windows type-bug An unexpected behavior, bug, or error labels Mar 18, 2019
@eryksun
Copy link
Contributor

eryksun commented Mar 18, 2019

The drive is retained when a rooted path is joined to a drive-absolute or UNC-absolute path. This is documented behavior 1:

When several absolute paths are given, the last is taken as an
anchor (mimicking os.path.join()’s behaviour):
        >>> PurePath('/etc', '/usr', 'lib64')
        PurePosixPath('/usr/lib64')
        >>> PureWindowsPath('c:/Windows', 'd:bar')
        PureWindowsPath('d:bar')

    However, in a Windows path, changing the local root doesn’t
    discard the previous drive setting:
    
        >>> PureWindowsPath('c:/Windows', '/Program Files')
        PureWindowsPath('c:/Program Files')

If you want to simply append directories to a path, use a relative path. For example:

    >>> Path('C:/Program Files') / Path('one/two/three.exe')
    WindowsPath('C:/Program Files/one/two/three.exe')

@eryksun eryksun closed this as completed Mar 18, 2019
@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.7 (EOL) end of life OS-windows type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

1 participant