33import os
44import os .path
55import unittest
6+ import tempfile
7+ import shutil
68from test .support import import_helper
79
810# Skip this test if the _testcapi module isn't available.
@@ -26,5 +28,88 @@ def test_capi_normalize_path(self):
2628 msg = f'input: { filename !r} expected output: { expected !r} ' )
2729
2830
31+ class RealpathTests (unittest .TestCase ):
32+ """Tests for _Py_wrealpath used by os.path.realpath"""
33+
34+ def test_realpath_long_path (self ):
35+ """Test that realpath handles paths longer than MAXPATHLEN (4096)"""
36+ if os .name == 'nt' :
37+ raise unittest .SkipTest ('POSIX-specific test' )
38+
39+ base = tempfile .mkdtemp ()
40+ original_cwd = os .getcwd ()
41+ try :
42+ os .chdir (base )
43+
44+ for i in range (85 ):
45+ dirname = f"d{ i :03d} _" + "x" * 44
46+ os .mkdir (dirname )
47+ os .chdir (dirname )
48+
49+ full_path = os .getcwd ()
50+
51+ self .assertGreater (len (full_path ), 4096 ,
52+ f"Path should exceed MAXPATHLEN, got { len (full_path )} " )
53+
54+ # Main test: realpath should not crash on long paths
55+ result = os .path .realpath (full_path )
56+
57+ self .assertTrue (os .path .isabs (result ))
58+ self .assertGreater (len (result ), 4096 )
59+ # Note: os.path.exists() may fail on very long paths
60+ # The important thing is realpath() doesn't crash
61+
62+ finally :
63+ os .chdir (original_cwd )
64+ shutil .rmtree (base , ignore_errors = True )
65+
66+ def test_realpath_nonexistent_with_strict (self ):
67+ """Test that realpath with strict=True raises for nonexistent paths"""
68+ if os .name == 'nt' :
69+ raise unittest .SkipTest ('POSIX-specific test' )
70+
71+ base = tempfile .mkdtemp ()
72+ try :
73+ nonexistent = os .path .join (base , "does_not_exist" , "subdir" )
74+
75+ # Without strict, should return the path
76+ result = os .path .realpath (nonexistent , strict = False )
77+ self .assertIsNotNone (result )
78+
79+ # With strict=True, should raise an error
80+ with self .assertRaises (OSError ):
81+ os .path .realpath (nonexistent , strict = True )
82+
83+ finally :
84+ shutil .rmtree (base , ignore_errors = True )
85+
86+ def test_realpath_symlink_long_path (self ):
87+ """Test realpath with symlinks in long paths"""
88+ if os .name == 'nt' :
89+ raise unittest .SkipTest ('POSIX-specific test' )
90+
91+ base = tempfile .mkdtemp ()
92+ try :
93+ # Create a long path
94+ current = base
95+ for i in range (30 ):
96+ dirname = f"d{ i :03d} _" + "x" * 44
97+ current = os .path .join (current , dirname )
98+ os .mkdir (current )
99+
100+ # Create a symlink pointing to the long path
101+ symlink = os .path .join (base , "link" )
102+ os .symlink (current , symlink )
103+
104+ # Resolve the symlink
105+ result = os .path .realpath (symlink )
106+
107+ self .assertEqual (os .path .normpath (result ), os .path .normpath (current ))
108+ self .assertGreater (len (result ), 1500 )
109+
110+ finally :
111+ shutil .rmtree (base , ignore_errors = True )
112+
113+
29114if __name__ == "__main__" :
30115 unittest .main ()
0 commit comments