1- # -*- coding: utf-8 -*-
2- from __future__ import absolute_import , print_function , unicode_literals
1+ # encoding: utf-8
32
4- import codecs
5- import fileinput
6- import io
3+ #import codecs
4+ #import fileinput
75import os
86import re
97import sys
108import warnings
11- from collections import OrderedDict
9+ # from ordereddict import OrderedDict
1210
13- from . compat import StringIO
11+ from compat import StringIO
1412
15- __escape_decoder = codecs .getdecoder ('unicode_escape' )
13+ # __escape_decoder = codecs.getdecoder('unicode_escape')
1614__posix_variable = re .compile ('\$\{[^\}]*\}' )
1715
1816
19- def decode_escaped (escaped ):
20- return __escape_decoder (escaped )[0 ]
17+ # def decode_escaped(escaped):
18+ # return __escape_decoder(escaped)[0]
2119
2220
2321def parse_line (line ):
@@ -39,17 +37,19 @@ def parse_line(line):
3937 v = v .encode ('unicode-escape' ).decode ('ascii' )
4038 quoted = v [0 ] == v [- 1 ] in ['"' , "'" ]
4139 if quoted :
42- v = decode_escaped (v [1 :- 1 ])
40+ #v = decode_escaped(v[1:-1])
41+ v = v [1 :- 1 ]
4342
4443 return k , v
4544
4645
47- class DotEnv ():
46+ class DotEnv (object ):
4847
49- def __init__ (self , dotenv_path , verbose = False ):
48+ def __init__ (self , dotenv_path , verbose = False , castvalue = None ):
5049 self .dotenv_path = dotenv_path
5150 self ._dict = None
5251 self .verbose = verbose
52+ self .castvalue = castvalue
5353
5454 def _get_stream (self ):
5555 self ._is_file = False
@@ -58,7 +58,7 @@ def _get_stream(self):
5858
5959 if os .path .exists (self .dotenv_path ):
6060 self ._is_file = True
61- return io . open (self .dotenv_path )
61+ return open (self .dotenv_path )
6262
6363 if self .verbose :
6464 warnings .warn ("File doesn't exist {}" .format (self .dotenv_path ))
@@ -70,23 +70,26 @@ def dict(self):
7070 if self ._dict :
7171 return self ._dict
7272
73- values = OrderedDict (self .parse ())
74- self ._dict = resolve_nested_variables (values )
73+ # values = OrderedDict(self.parse())
74+ self ._dict = resolve_nested_variables (self . parse () )
7575 return self ._dict
7676
7777 def parse (self ):
78+ dic = {}
7879 f = self ._get_stream ()
7980
8081 for line in f :
8182 key , value = parse_line (line )
8283 if not key :
8384 continue
8485
85- yield key , value
86+ dic [ key ] = ( lambda : value , lambda : self . castvalue ( value ))[ bool ( self . castvalue and callable ( self . castvalue ))]()
8687
8788 if self ._is_file :
8889 f .close ()
8990
91+ return dic
92+
9093 def set_as_environment_variables (self , override = False ):
9194 """
9295 Load the current dotenv as system environemt variable.
@@ -118,6 +121,13 @@ def get_key(dotenv_path, key_to_get):
118121 """
119122 return DotEnv (dotenv_path , verbose = True ).get (key_to_get )
120123
124+ def lines_to_file (dotenv_path , lines ):
125+ f = open (dotenv_path , 'w' )
126+ try :
127+ for line in lines :
128+ f .write ("%s\n " % line )
129+ finally :
130+ f .close ()
121131
122132def set_key (dotenv_path , key_to_set , value_to_set , quote_mode = "always" ):
123133 """
@@ -134,20 +144,29 @@ def set_key(dotenv_path, key_to_set, value_to_set, quote_mode="always"):
134144 if " " in value_to_set :
135145 quote_mode = "always"
136146
137- line_template = '{}="{}"' if quote_mode == "always" else '{}={}'
147+ line_template = ( '{}={}' , '{}= "{}"')[ quote_mode == "always" ]
138148 line_out = line_template .format (key_to_set , value_to_set )
139149
140150 replaced = False
141- for line in fileinput .input (dotenv_path , inplace = True ):
142- k , v = parse_line (line )
143- if k == key_to_set :
144- replaced = True
145- line = line_out
146- print (line , end = '' )
151+ f = open (dotenv_path , 'r' )
152+ try :
153+ lines = []
154+ for line in f .readlines ():
155+ k , v = parse_line (line )
156+ if k == key_to_set :
157+ replaced = True
158+ line = line_out
159+ lines .append (line )
160+ #print line, # end not support in python 2.4
161+ finally : f .close ()
162+
163+ if replaced : lines_to_file (dotenv_path , lines )
147164
148165 if not replaced :
149- with io .open (dotenv_path , "a" ) as f :
166+ f = open (dotenv_path , "a" )
167+ try :
150168 f .write ("{}\n " .format (line_out ))
169+ finally : f .close ()
151170
152171 return True , key_to_set , value_to_set
153172
@@ -165,12 +184,18 @@ def unset_key(dotenv_path, key_to_unset, quote_mode="always"):
165184 warnings .warn ("can't delete from %s - it doesn't exist." % dotenv_path )
166185 return None , key_to_unset
167186
168- for line in fileinput .input (dotenv_path , inplace = True ):
169- k , v = parse_line (line )
170- if k == key_to_unset :
171- removed = True
172- line = ''
173- print (line , end = '' )
187+ lines = []
188+ f = open (dotenv_path , 'r' )
189+ try :
190+ for line in f .readlines ():
191+ k , v = parse_line (line )
192+ if k == key_to_unset :
193+ removed = True
194+ line = ''
195+ lines .append (line )
196+ finally : f .close ()
197+
198+ if removed : lines_to_file (dotenv_path , lines )
174199
175200 if not removed :
176201 warnings .warn ("key %s not removed from %s - key doesn't exist." % (key_to_unset , dotenv_path ))
@@ -245,9 +270,9 @@ def find_dotenv(filename='.env', raise_error_if_not_found=False, usecwd=False):
245270 return ''
246271
247272
248- def load_dotenv (dotenv_path = None , stream = None , verbose = False , override = False ):
273+ def load_dotenv (dotenv_path = None , stream = None , verbose = False , override = False , castvalue = None ):
249274 f = dotenv_path or stream or find_dotenv ()
250- return DotEnv (f , verbose = verbose ).set_as_environment_variables (override = override )
275+ return DotEnv (f , verbose = verbose , castvalue = castvalue ).set_as_environment_variables (override = override )
251276
252277
253278def dotenv_values (dotenv_path = None , stream = None , verbose = False ):
0 commit comments