
Python Path.relative_to 사용법
pathlib.PurePath.relative_to()는 기준 경로를 기준으로 상대 경로를 계산할 때 쓰는 메서드다. 다만 os.path.relpath()처럼 아무 경로나 자동으로 상대화하는 함수는 아니다. Python 3.14 공식 문서는 이 메서드를 문자열 기반의 lexical 연산으로 설명하고, 조건이 맞지 않으면 ValueError를 발생시킨다고 명시한다.
실무 기준은 세 가지다. 기준 경로가 실제로 현재 경로의 상위 경로인지, 심볼릭 링크를 먼저 정리해야 하는지, 그리고 Python 3.12 이상에서 walk_up=True가 필요한지다. 이 글은 Python 3.14 공식 문서를 기준으로 Path.relative_to()를 안전하게 쓰는 판단 기준만 정리한다.
Path.relative_to는 언제 쓰면 될까?
다음 조건이면 Path.relative_to()가 잘 맞는다.
- 두 경로의 관계를 문자열 규칙으로 확인할 수 있다.
- 기준 경로가 현재 경로의 실제 상위 경로인지 명확하다.
pathlib.Path기반 코드에서 상대 경로 표현만 간단히 만들고 싶다.
반대로 임의의 두 경로를 억지로라도 상대 경로로 만들고 싶다면 이 메서드의 동작을 먼저 이해해야 한다. Python 공식 문서는 입력 경로의 anchor가 다르거나 상하 관계가 맞지 않으면 ValueError가 난다고 설명한다.
기본 동작은 무엇일까?
Python 3.14 문서의 시그니처는 PurePath.relative_to(other, walk_up=False)다. 기본값에서는 현재 경로가 other로 시작해야 하며, 그렇지 않으면 예외가 발생한다.
from pathlib import Path
config_path = Path("/srv/app/config/settings.toml")
print(config_path.relative_to("/srv"))
# app/config/settings.toml
print(config_path.relative_to("/usr"))
# ValueError
즉 이 메서드는 "가능하면 상대 경로를 만들어 준다"보다 "정해진 포함 관계가 맞는지 확인하면서 잘라낸다"에 가깝다. 그래서 배포 경로 검증, 업로드 루트 검증, 로그 경로 정규화 같은 코드에서 더 예측 가능하다.
walk_up=True는 언제 필요할까?
Python 공식 문서는 3.12부터 walk_up 매개변수가 추가됐다고 밝힌다. 이 값을 True로 두면 하위 경로 관계가 아니더라도 .. 조각을 추가해서 상대 경로를 만들 수 있다.
from pathlib import Path
path = Path("/srv/app/config/settings.toml")
print(path.relative_to("/srv/app", walk_up=True))
# config/settings.toml
print(path.relative_to("/srv/log", walk_up=True))
# ../app/config/settings.toml
이 옵션은 "같은 파일시스템 anchor 안에서 상대 표현이 필요하다"는 조건이 분명할 때만 쓰는 편이 좋다. anchor가 다르면 여전히 ValueError가 발생할 수 있다.
심볼릭 링크가 있으면 왜 resolve()를 먼저 보라고 할까?
Python 문서는 relative_to()가 실제 파일시스템을 확인하지 않는 lexical 연산이라고 설명한다. 따라서 경로 문자열에 심볼릭 링크가 섞여 있으면 눈에 보이는 상하 관계와 실제 경로 구조가 다를 수 있다.
공식 문서는 이런 경우 필요하면 먼저 resolve()를 호출해 심볼릭 링크를 해석하라고 권고한다. 경로 접근 제어, 허용 디렉터리 검사, 파일 업로드 저장 경로 검증처럼 보안상 경계가 중요한 코드라면 이 순서가 특히 중요하다.
from pathlib import Path
base = Path("/srv/data").resolve()
target = Path("/srv/data/current/../reports/today.csv").resolve()
relative = target.relative_to(base)
print(relative)
os.path.relpath와는 무엇이 다를까?
Python 3.14 문서는 비교 표에서 os.path.relpath()에 대응하는 pathlib 도구로 PurePath.relative_to()를 제시하면서도, 두 동작이 완전히 같지는 않다고 별도 각주로 설명한다.
공식 문서 기준으로 os.path.relpath()는 내부적으로 절대 경로화와 .. 정리를 수행하는 반면, relative_to()는 lexical 연산이어서 입력 anchor가 다르거나 절대/상대 경로 타입이 섞이면 ValueError를 낸다. 즉 "실패하면 예외로 드러나는 더 엄격한 API"로 이해하는 편이 맞다.
실무에서는 어떤 기준이 무난할까?
- 상위 경로 포함 관계를 검증하면서 상대 경로를 만들고 싶다면
Path.relative_to()가 적합하다. - 심볼릭 링크나
..조각이 섞일 수 있으면 먼저resolve()여부를 판단한다. - Python 3.11 이하 호환이 필요하면
walk_up를 전제로 설계하면 안 된다. - 경로 관계가 성립하지 않을 수 있다면
try/except ValueError로 실패 경로를 분기한다.
대부분의 서비스 코드에서는 "루트 디렉터리 아래에 있는지 확인한 뒤 상대 경로만 저장" 같은 패턴에 가장 잘 맞는다. 반면 사용자가 넘긴 임의의 두 경로를 무조건 상대화하는 용도라면 예외 처리 전략을 먼저 세워야 한다.
FAQ
Path.relative_to는 파일이 실제로 존재해야 동작할까?
아니다. Python 공식 문서는 이 메서드가 파일시스템을 확인하지 않는 lexical 연산이라고 설명한다. 따라서 경로 문자열만으로 계산되며, 존재 여부를 따로 검사하지 않는다.
walk_up=True를 쓰면 항상 상대 경로를 만들 수 있을까?
항상 그렇지는 않다. Python 공식 문서는 입력 경로의 anchor가 다르거나 절대/상대 경로 타입이 다르면 ValueError가 발생할 수 있다고 설명한다.
보안 검증 코드에서 어떤 순서가 안전할까?
심볼릭 링크 가능성이 있으면 먼저 resolve()로 실제 경로를 정규화한 뒤 relative_to()로 허용 루트 내부인지 확인하는 편이 더 안전하다. Python 공식 문서도 심볼릭 링크가 있을 수 있으면 resolve()를 먼저 호출하라고 안내한다.
참고 자료
'프로그래밍 > C, C++, Java, Python' 카테고리의 다른 글
| Python Path.copy 사용법 (0) | 2026.06.07 |
|---|---|
| Python Path.walk 사용법 (0) | 2026.06.02 |
| Python tomllib 사용법 (0) | 2026.05.29 |
| Python venv와 virtualenv는 무엇이 다를까? 프로젝트별 선택 기준 정리 (0) | 2026.05.17 |
| Python uuid7은 언제 써야 할까? 정렬 가능한 ID 선택 기준 정리 (0) | 2026.05.12 |





