Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can Python3's pathlib be used portably between Linux and Windows systems?

I'm writing some software in Python3 intended to take a backup of a directory structure on a Windows client, and send it to a Linux server.

The problem I'm having is how to deal with Windows and Linux file paths. I need the Windows client to create an object representing the relative path to the source file, send that relative path to the server, so the server knows which subdirectory to write the file to in the destination folder, and then send the actual data.

Sending the actual data is not a problem, but how do I send a Windows relative path to a Linux system? I tried doing it as strings, using os.path, but that quickly became a mess. I'm looking at using pathlib.

If I can create a path object of some sort, I can use pickle to serialize it, and send it to the server. What object would I use from pathlib to represent the path though?

Path() seems to create an instance of the class that works for the current filesystem (PosixPath or WindowsPath), which aren't portable. If I make a WindowsPath object on the Windows client, Linux won't be able to deserialize it, as you can't even instantiate a WindowsPath object on a Linux system.

It looks like I could use a PureWindowsPath object, and send that to Linux, but how do I convert the PureWindowsPath object (that represents a relative path) to either a PosixPath, or at least a PurePosixPath?

Is that possible? Or am I thinking about it all wrong?

like image 841
John Avatar asked Jan 01 '19 18:01

John


People also ask

What is Pathlib used for?

Pathlib module in Python provides various classes representing file system paths with semantics appropriate for different operating systems. This module comes under Python's standard utility modules. Path classes in Pathlib module are divided into pure paths and concrete paths.

What is the main difference between the Pathlib and OS libraries?

The OS library will return a string, whereas the Pathlib will return an object of PosixPath. The benefit of having PosixPath returned is that we can directly use the returned object to do a lot more further operations.

Does Pathlib replace OS path?

The pathlib module replaces many of these filesystem-related os utilities with methods on the Path object. Notice that the pathlib code puts the path first because of method chaining!

Is Pathlib a standard?

Python pathlib tutorial shows how to work with files and directories in Python with pathlib module. The pathlib is a Python module which provides an object API for working with files and directories. The pathlib is a standard module. Path is the core object to work with files.


1 Answers

pathlib is an OO library, not a communication protocol. Just send strings.

Windows can handle paths with forward slashes just fine, and both pathlib and os.path can normalise such paths for you. You probably want to normalise paths in your protocol to use POSIX path separators (forward slashes).

You can convert relative Windows paths to POSIX paths using pathlib.PurePosixPath(), for example:

>>> from pathlib import Path, PurePosixPath
>>> Path('relative\path\on\windows')
WindowsPath('relative\path\on\windows')
>>> PurePosixPath(_)
PurePosixPath('relative/path/on/windows')
>>> str(_)
'relative/path/on/windows'

If your server receives a relative paths using Windows conventions, use PureWindowsPath() to convert it to a pathlib object, then pass that to Path() to convert:

>>> from pathlib import Path, PureWindowsPath
>>> received = 'relative\path\on\windows'
>>> PureWindowsPath(received)
PureWindowsPath('relative/path/on/windows')
>>> Path(_)
PosixPath('relative/path/on/windows')

If you keep paths as strings, then you can use str.replace(os.altsep, os.sep) to achieve the same on the Windows side before sending:

>>> import os
>>> p = 'relative\path\on\windows'
>>> p.replace(os.altsep, os.sep)
'relative/path/on/windows'

and you can always just use relative_path.replace('\\', os.sep) to force the issue.

like image 116
Martijn Pieters Avatar answered Oct 06 '22 00:10

Martijn Pieters