33

I'm trying to add a directory to PATH with code like this:

PROJECT_DIR = Path(__file__).parents[2]
sys.path.append(
    PROJECT_DIR / 'apps'
)

It doesn't work. If I do print sys.path I see something like this:

[..., PosixPath('/opt/project/apps')]

How should I fix this code? Is it normal to write str(PROJECT_DIR / 'apps')?

wim
  • 338,267
  • 99
  • 616
  • 750
kharandziuk
  • 12,020
  • 17
  • 63
  • 121
  • 1
    why would you want to avoid using `str`? – hiro protagonist Sep 21 '15 at 17:39
  • 2
    I don't want to avoid this. I just ask what the proper way to use pathlib. – kharandziuk Sep 21 '15 at 17:40
  • 1
    re. you second question (since it's not covered in answers): yes, it's normal. Documentation mentions `str`: [The string representation of a path is the raw filesystem path itself (in native form, e.g. with backslashes under Windows), which you can pass to any function taking a file path as a string.](https://docs.python.org/3/library/pathlib.html#operators) – vaultah Sep 21 '15 at 17:40

4 Answers4

44

From the docs:

A program is free to modify this list for its own purposes. Only strings should be added to sys.path; all other data types are ignored during import.

Add the path as a string to sys.path:

PROJECT_DIR = Path(__file__).parents[2]
sys.path.append(
    str(PROJECT_DIR / 'apps')
)

PROJECT_DIR is an instance of PosixPath which has all the goodies like / and .parents etc. You need to convert it to a string if you want to append it to sys.path.

hiro protagonist
  • 44,693
  • 14
  • 86
  • 111
  • 1
    You may want to `resolve()` the Path before adding it to sys.path. That makes it absolute -- __file__ isnt't always absolute. – florisla Aug 05 '17 at 08:02
  • @florisla as this is done at runtime there is no need for that (as long as you do not move the modules before they are imported). – hiro protagonist Aug 05 '17 at 08:03
6

Support for path-like-objects on sys.path is coming (see this pull request) but not here yet.

Tom
  • 7,269
  • 1
  • 42
  • 69
0

You could also use os.fspath. It return the file system representation of the path.

import os
    
PROJECT_DIR = Path(__file__).parents[2]
APPS_DIR = PROJECT_DIR / 'apps'
sys.path.append(os.fspath(APPS_DIR))

Documentation: https://docs.python.org/3/library/os.html#os.fspath

Jack Klimov
  • 378
  • 2
  • 10
  • [May as well just use `str()`](https://github.com/python/cpython/blob/b4d54a332ed593c9fcd0da25684c622a251d03ce/Lib/pathlib.py#L470-L471) – wim Nov 24 '22 at 08:24
-11
project_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)),"..","..")
sys.path.append(os.path.join(project_dir,"apps"))
#or maybe you need it at the start of the path
sys.path.insert(0,os.path.join(project_dir,"apps"))

why are you using this weird pathlib library instead of pythons perfectly good path utils?

Joran Beasley
  • 110,522
  • 12
  • 160
  • 179
  • 1
    may be a matter of taste - pathlib is pretty nice! – hiro protagonist Sep 21 '15 at 17:34
  • 1
    This does not answer the question. – vaultah Sep 21 '15 at 17:35
  • yeah its not using pathlib ... so it only answers the question if we assume (perhaps wrongly) that OP just really wants to extend the path... and pathlib was just something he thought he needed (or perhaps needs it for other reasons) – Joran Beasley Sep 21 '15 at 17:37
  • @hiroprotagonist yeah :) your answer is probably the right one (I upvoted it ... ) but figure ill leave this here just in case OP just wasnt familliar with builtin path tools ... – Joran Beasley Sep 21 '15 at 17:38
  • 2
    I guess you miss this part `.parents[2]` in your answer – kharandziuk Sep 21 '15 at 17:38
  • So the answer on your question is "pathlib/unipath/any_other_oo_path_lib helps me to avoid mistakes" – kharandziuk Sep 21 '15 at 17:41
  • 1
    @Joran Beasley: by all means leave the answer! `os.path` is a perfectly fine library indeed! and for python <3 none of the `pathlib` stuff will work. – hiro protagonist Sep 21 '15 at 17:42
  • pathlib backported to python2.* – kharandziuk Sep 21 '15 at 17:42
  • 1
    except it clearly lead to mistakes that you would not have had using the builtin ... and the mistakes were so hard you had to come ask SO for help :P but yes i see... i guess ... I still suggest builtins when they work for the task at hand @hiroprotagonist lol i read that as python love :P instead of python less than 3 :P – Joran Beasley Sep 21 '15 at 17:43
  • 2
    python love! (and: pathlib is builtin in python >3 and evidently backported to python 2.* [as mentioned by kharandziuk]). – hiro protagonist Sep 21 '15 at 17:47
  • "this weird [pathlib](https://docs.python.org/3/library/pathlib.html) library" LOL. This answer aged like fine milk. – wim Nov 24 '22 at 08:20