0

I have a function that replaces the beginning of a path by another path in a bunch of strings read from a configuration file. I do this because I want to move the data directory to a new place, the first time someone start my application (which is a fork of another application). It works well on linux and MacOS, but fails on Windows because the paths are case insentive and my replacement method is case sensitive.

Here is my function:

def replace_src_dest_in_config(src: str, dest: str, config: dict):
    """Replace all occurrences of the string src by the str dest in the
    relevant values of the config dictionary.
    """
    # adjust all paths to point to the new user dir
    for k, v in config.items():
        if isinstance(v, str) and v.startswith(src):
            config[k] = v.replace(src, dest)

I could make a special case for windows, pass all those strings through a .lower() step, but I'm wondering if there isn't a better high-level way of doing this with pathlib.

Edit to add an example: if I want to replace C:\Users\USERNAME\AppData\Roaming\MyApp with C:\Users\USERNAME\AppData\Roaming\MyForkedApp, but my config file has the path stored as c:\users\username\appdata\roaming\myapp, the function will not work.

PiRK
  • 893
  • 3
  • 9
  • 24
  • Note, Linux and Window based OS has a different "file path separator" as [available here](https://stackoverflow.com/questions/2227925). So, use `os.path()` from python which will take care of this! – Mr. Hobo Dec 07 '20 at 07:34
  • Also, please add an example of what exactly is the problem you are facing. – Mr. Hobo Dec 07 '20 at 07:35

1 Answers1

0

I found this solution: use os.path.normcase on all strings prior to replacing src with dest.

os.path.normcase returns the string unchanged on Mac and Linux, and returns the lowercase string on Windows (and it also normalizes the path separator).

def replace_src_dest_in_config(src: str, dest: str, config: dict):
    norm_src = os.path.normcase(src)
    norm_dest = os.path.normcase(dest)
    # adjust all paths to point to the new user dir
    for k, v in config.items():
        if isinstance(v, str):
            norm_path = os.path.normcase(v)
            if norm_path.startswith(norm_src):
                config[k] = norm_path.replace(norm_src, norm_dest)
PiRK
  • 893
  • 3
  • 9
  • 24