5252import ansible_mitogen .target # TODO: circular import
5353from mitogen .core import b
5454from mitogen .core import bytes_partition
55- from mitogen .core import str_partition
5655from mitogen .core import str_rpartition
5756from mitogen .core import to_text
5857
104103LOG = logging .getLogger (__name__ )
105104
106105
107- if mitogen .core .PY3 :
108- shlex_split = shlex .split
109- else :
110- def shlex_split (s , comments = False ):
111- return [mitogen .core .to_text (token )
112- for token in shlex .split (str (s ), comments = comments )]
106+ def shlex_split_b (s ):
107+ """
108+ Use shlex.split() to split characters in some single-byte encoding, without
109+ knowing what that encoding is. The input is bytes, the output is a list of
110+ bytes.
111+ """
112+ assert isinstance (s , mitogen .core .BytesType )
113+ if mitogen .core .PY3 :
114+ return [
115+ t .encode ('latin1' )
116+ for t in shlex .split (s .decode ('latin1' ), comments = True )
117+ ]
118+
119+ return [t for t in shlex .split (s , comments = True )]
113120
114121
115122class TempFileWatcher (object ):
@@ -165,13 +172,19 @@ class EnvironmentFileWatcher(object):
165172 A more robust future approach may simply be to arrange for the persistent
166173 interpreter to restart when a change is detected.
167174 """
175+ # We know nothing about the character set of /etc/environment or the
176+ # process environment.
177+ environ = getattr (os , 'environb' , os .environ )
178+
168179 def __init__ (self , path ):
169180 self .path = os .path .expanduser (path )
170181 #: Inode data at time of last check.
171182 self ._st = self ._stat ()
172183 #: List of inherited keys appearing to originated from this file.
173- self ._keys = [key for key , value in self ._load ()
174- if value == os .environ .get (key )]
184+ self ._keys = [
185+ key for key , value in self ._load ()
186+ if value == self .environ .get (key )
187+ ]
175188 LOG .debug ('%r installed; existing keys: %r' , self , self ._keys )
176189
177190 def __repr__ (self ):
@@ -185,7 +198,7 @@ def _stat(self):
185198
186199 def _load (self ):
187200 try :
188- fp = codecs . open (self .path , 'r' , encoding = 'utf-8 ' )
201+ fp = open (self .path , 'rb ' )
189202 try :
190203 return list (self ._parse (fp ))
191204 finally :
@@ -199,36 +212,36 @@ def _parse(self, fp):
199212 """
200213 for line in fp :
201214 # ' #export foo=some var ' -> ['#export', 'foo=some var ']
202- bits = shlex_split (line , comments = True )
203- if (not bits ) or bits [0 ].startswith ('#' ):
215+ bits = shlex_split_b (line )
216+ if (not bits ) or bits [0 ].startswith (b ( '#' ) ):
204217 continue
205218
206- if bits [0 ] == u 'export' :
219+ if bits [0 ] == b ( 'export' ) :
207220 bits .pop (0 )
208221
209- key , sep , value = str_partition ( u ' ' .join (bits ), u '=' )
222+ key , sep , value = bytes_partition ( b ( ' ' ) .join (bits ), b ( '=' ) )
210223 if key and sep :
211224 yield key , value
212225
213226 def _on_file_changed (self ):
214227 LOG .debug ('%r: file changed, reloading' , self )
215228 for key , value in self ._load ():
216- if key in os .environ :
229+ if key in self .environ :
217230 LOG .debug ('%r: existing key %r=%r exists, not setting %r' ,
218- self , key , os .environ [key ], value )
231+ self , key , self .environ [key ], value )
219232 else :
220233 LOG .debug ('%r: setting key %r to %r' , self , key , value )
221234 self ._keys .append (key )
222- os .environ [key ] = value
235+ self .environ [key ] = value
223236
224237 def _remove_existing (self ):
225238 """
226239 When a change is detected, remove keys that existed in the old file.
227240 """
228241 for key in self ._keys :
229- if key in os .environ :
242+ if key in self .environ :
230243 LOG .debug ('%r: removing old key %r' , self , key )
231- del os .environ [key ]
244+ del self .environ [key ]
232245 self ._keys = []
233246
234247 def check (self ):
0 commit comments