@@ -144,7 +144,16 @@ def resolve(path, posix=True):
144144replace_illegal_chars_exc_spaces = re .compile (illegal_chars_exc_spaces_re ).sub
145145
146146
147- def portable_filename (filename , preserve_spaces = False ):
147+ posix_legal_punctuation = r"!@#$%^&\*\(\)-_=\+\[\{\]\}\\\|;:'\",<.>\/\?`~"
148+ posix_legal_chars = r"A-Za-z0-9" + posix_legal_punctuation
149+ posix_legal_chars_inc_spaces = posix_legal_chars + legal_spaces
150+ posix_illegal_chars_re = r"[^" + posix_legal_chars + r"]"
151+ posix_illegal_chars_exc_spaces_re = r"[^" + posix_legal_chars_inc_spaces + r"]"
152+ replace_illegal_posix_chars = re .compile (posix_illegal_chars_re ).sub
153+ replace_illegal_posix_chars_exc_spaces = re .compile (posix_illegal_chars_exc_spaces_re ).sub
154+
155+
156+ def portable_filename (filename , preserve_spaces = False , posix_only = False ):
148157 """
149158 Return a new name for `filename` that is portable across operating systems.
150159
@@ -170,55 +179,29 @@ def portable_filename(filename, preserve_spaces=False):
170179 if not filename :
171180 return '_'
172181
173- if preserve_spaces :
174- filename = replace_illegal_chars_exc_spaces ('_' , filename )
182+ if posix_only :
183+ if preserve_spaces :
184+ filename = replace_illegal_posix_chars_exc_spaces ('_' , filename )
185+ else :
186+ filename = replace_illegal_posix_chars ('_' , filename )
175187 else :
176- filename = replace_illegal_chars ('_' , filename )
177-
178- # these are illegal both upper and lowercase and with or without an extension
179- # we insert an underscore after the base name.
180- windows_illegal_names = set ([
181- 'com1' , 'com2' , 'com3' , 'com4' , 'com5' , 'com6' , 'com7' , 'com8' , 'com9' ,
182- 'lpt1' , 'lpt2' , 'lpt3' , 'lpt4' , 'lpt5' , 'lpt6' , 'lpt7' , 'lpt8' , 'lpt9' ,
183- 'aux' , 'con' , 'nul' , 'prn'
184- ])
185-
186- basename , dot , extension = filename .partition ('.' )
187- if basename .lower () in windows_illegal_names :
188- filename = '' .join ([basename , '_' , dot , extension ])
189-
190- # no name made only of dots.
191- if set (filename ) == set (['.' ]):
192- filename = 'dot' * len (filename )
193-
194- # replaced any leading dotdot
195- if filename != '..' and filename .startswith ('..' ):
196- while filename .startswith ('..' ):
197- filename = filename .replace ('..' , '__' , 1 )
198-
199- return filename
200-
201-
202- posix_legal_punctuation = r"!@#$%^&\*\(\)-_=\+\[\{\]\}\\\|;:'\",<.>\/\?`~\ "
203- posix_legal_characters = r"A-Za-z0-9" + posix_legal_punctuation
204- posix_illegal_characters_re = r"[^" + posix_legal_characters + r"]"
205- replace_illegal_posix_chars = re .compile (posix_illegal_characters_re ).sub
206-
207-
208- def posix_safe_filename (filename ):
209- """
210- Return a new name for `filename` that is portable across POSIX systems.
211-
212- Filenames returned by `posix_safe_filename` are not guarenteed to be valid
213- on Windows systems as they may contain characters not allowed in Windows
214- filenames.
215- """
216- filename = toascii (filename , translit = True )
217-
218- if not filename :
219- return '_'
220-
221- filename = replace_illegal_posix_chars ('_' , filename )
188+ if preserve_spaces :
189+ filename = replace_illegal_chars_exc_spaces ('_' , filename )
190+ else :
191+ filename = replace_illegal_chars ('_' , filename )
192+
193+ if not posix_only :
194+ # these are illegal both upper and lowercase and with or without an extension
195+ # we insert an underscore after the base name.
196+ windows_illegal_names = set ([
197+ 'com1' , 'com2' , 'com3' , 'com4' , 'com5' , 'com6' , 'com7' , 'com8' , 'com9' ,
198+ 'lpt1' , 'lpt2' , 'lpt3' , 'lpt4' , 'lpt5' , 'lpt6' , 'lpt7' , 'lpt8' , 'lpt9' ,
199+ 'aux' , 'con' , 'nul' , 'prn'
200+ ])
201+
202+ basename , dot , extension = filename .partition ('.' )
203+ if basename .lower () in windows_illegal_names :
204+ filename = '' .join ([basename , '_' , dot , extension ])
222205
223206 # no name made only of dots.
224207 if set (filename ) == set (['.' ]):
0 commit comments