ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/Development/ray/src/common/pyradlib/pyrad_proc.py
(Generate patch)

Comparing ray/src/common/pyradlib/pyrad_proc.py (file contents):
Revision 1.1 by schorsch, Mon Mar 28 17:52:11 2016 UTC vs.
Revision 1.5 by schorsch, Wed Apr 27 16:29:48 2016 UTC

# Line 22 | Line 22 | class ProcMixin():
22          '''Process and pipeline management for Python Radiance scripts
23          '''
24          def raise_on_error(self, actstr, e):
25 <                raise Error('Unable to %s - %s' % (actstr, str(e)))
25 >                try: self._strtypes
26 >                except AttributeError: self.__configure_subprocess()
27 >                if hasattr(e, 'strerror'): eb = e.strerror
28 >                elif isinstance(e, self._strtypes): eb = e
29 >                else: eb = e
30 >                if isinstance(eb, type(b'')):
31 >                        estr = eb.decode(encoding='utf-8', errors='ignore')
32 >                else: estr = eb
33 >                raise Error('Unable to %s - %s' % (actstr, estr)) #
34  
35          def __configure_subprocess(self):
36                  '''Prevent subprocess module failure in frozen scripts on Windows.
37                     Prevent console windows from popping up when not console based.
38 <                   Make sure we use the version specific string types.
38 >                   Make sure we use the version-specific string types.
39                  '''
40                  # On Windows, sys.stdxxx may not be available when:
41                  # - built as *.exe with "pyinstaller --noconsole"
# Line 52 | Line 60 | class ProcMixin():
60                  else: self._pipeargs = {}
61                  # type names vary between Py2.7 and 3.x
62                  self._strtypes = (type(b''), type(u''))
55                # private attribute to indicate established configuration
56                self.__proc_mixin_setup = True
63  
64          def qjoin(self, sl):
65                  '''Join a list with quotes around each element containing whitespace.
# Line 66 | Line 72 | class ProcMixin():
72                          return s
73                  return  ' '.join([_q(s) for s in sl])
74  
75 +        def __parse_args(self, _in, out):
76 +                try: self._strtypes
77 +                except AttributeError: self.__configure_subprocess()
78 +                instr = ''
79 +                if _in == PIPE:
80 +                        stdin = _in
81 +                elif isinstance(_in, self._strtypes):
82 +                        if not getattr(self, 'donothing', None):
83 +                                stdin = open(_in, 'rb')
84 +                        else: stdin = None
85 +                        instr = ' < "%s"' % _in
86 +                elif hasattr(_in, 'read'):
87 +                        stdin = _in
88 +                        instr = ' < "%s"' % _in.name
89 +                else: stdin = self._stdin
90 +                outstr = ''
91 +                if out == PIPE:
92 +                        stdout = out
93 +                elif isinstance(out, self._strtypes):
94 +                        if not getattr(self, 'donothing', None):
95 +                                stdout = open(out, 'wb')
96 +                        else: stdout = None
97 +                        outstr = ' > "%s"' % out
98 +                elif hasattr(out, 'write'):
99 +                        stdout = out
100 +                        outstr = ' > "%s"' % out.name
101 +                else: stdout = self._stdout
102 +                return stdin, stdout, instr, outstr
103 +
104          def call_one(self, cmdl, actstr, _in=None, out=None,
105                          universal_newlines=False):
106                  '''Create a single subprocess, possibly with an incoming and outgoing
# Line 90 | Line 125 | class ProcMixin():
125                  If _in or out is a PIPE, the caller should call p.wait() on the
126                  returned Popen instance after writing to and closing it.
127                  '''
128 <                try: self.__proc_mixin_setup
94 <                except AttributeError: self.__configure_subprocess()
95 <                if _in == PIPE: stdin = _in
96 <                elif isinstance(_in, self._strtypes): stdin = open(_in, 'rb')
97 <                elif hasattr(_in, 'read'): stdin = _in
98 <                else: stdin = self._stdin
99 <                if out == PIPE: stdout = out
100 <                elif isinstance(out, self._strtypes): stdout = open(out, 'wb')
101 <                elif hasattr(out, 'write'): stdout = out
102 <                else: stdout = self._stdout
103 <                displ = cmdl[:]
104 <                if isinstance(_in, self._strtypes): displ[:0] = [_in, '>']
105 <                if isinstance(out, self._strtypes): displ.extend(['>', out])
128 >                stdin, stdout, instr, outstr = self.__parse_args(_in, out)
129                  if getattr(self, 'verbose', None):
130                          sys.stderr.write('### %s \n' % actstr)
131 <                        sys.stderr.write(self.qjoin(displ) + '\n')
131 >                        sys.stderr.write(self.qjoin(cmdl) + instr + outstr + '\n')
132                  if not getattr(self, 'donothing', None):
133 <                        try: p = subprocess.Popen(cmdl, stdin=stdin, stdout=stdout,
134 <                                        stderr=self._stderr,
133 >                        try: p = subprocess.Popen(cmdl,
134 >                                        stdin=stdin, stdout=stdout, stderr=self._stderr,
135                                          universal_newlines=universal_newlines, **self._pipeargs)
136                          except Exception as e:
137 <                                self.raise_on_error(actstr, str(e))
137 >                                self.raise_on_error(actstr, e)
138                          if stdin != PIPE and stdout != PIPE:
139                                  # caller needs to wait after reading or writing (else deadlock)
140                                  res = p.wait()
141                                  if res != 0:
142                                          self.raise_on_error(actstr,
143                                                          'Nonzero exit (%d) from command [%s].'
144 <                                                        % (res, self.qjoin(displ)))
144 >                                                        % (res, self.qjoin(cmdl)+instr+outstr+'\n'))
145                          return p
146  
147          def call_two(self, cmdl_1, cmdl_2, actstr_1, actstr_2, _in=None, out=None,
# Line 131 | Line 154 | class ProcMixin():
154                  If _in or out is PIPE, the caller should call p.wait() on both
155                  returned popen instances after writing to and closing the first on .
156                  '''
157 <                try: self.__proc_mixin_setup
135 <                except AttributeError: self.__configure_subprocess()
136 <                if _in == PIPE: stdin = _in
137 <                elif isinstance(_in, self._strtypes): stdin = open(_in, 'rb')
138 <                elif hasattr(_in, 'read'): stdin = _in
139 <                else: stdin = self._stdin
140 <                outendstr = '\n'
141 <                if out == PIPE:
142 <                        stdout = out
143 <                elif isinstance(out, self._strtypes):
144 <                        stdout = open(out, 'wb')
145 <                        outendstr = ' > "%s"\n' % out
146 <                elif hasattr(out, 'write'):
147 <                        stdout = out
148 <                        outendstr = ' > "%s"\n' % out.name
149 <                else: stdout = self._stdout
157 >                stdin, stdout, instr, outstr = self.__parse_args(_in, out)
158                  if getattr(self, 'verbose', None):
159                          sys.stderr.write('### %s \n' % actstr_1)
160                          sys.stderr.write('### %s \n' % actstr_2)
161 <                        sys.stderr.write(self.qjoin(cmdl_1) + ' | ')
161 >                        sys.stderr.write(self.qjoin(cmdl_1) + instr + ' | ')
162                  if not getattr(self, 'donothing', None):
163 <                        try: p1 = subprocess.Popen(cmdl_1, stdin=stdin,
164 <                                        stdout=PIPE, stderr=self._stderr, **self._pipeargs)
163 >                        try: p1 = subprocess.Popen(cmdl_1,
164 >                                        stdin=stdin, stdout=PIPE, stderr=self._stderr,
165 >                                        **self._pipeargs)
166                          except Exception as e:
167 <                                self.raise_on_error(actstr_1, str(e))
167 >                                self.raise_on_error(actstr_1, e)
168                  if getattr(self, 'verbose', None):
169 <                        sys.stderr.write(self.qjoin(cmdl_2) + outendstr)
169 >                        sys.stderr.write(self.qjoin(cmdl_2) + outstr + '\n')
170                  if not getattr(self, 'donothing', None):
171                          try:
172 <                                p2 = subprocess.Popen(cmdl_2, stdin=p1.stdout, stdout=stdout,
173 <                                                stderr=self._stderr,
172 >                                p2 = subprocess.Popen(cmdl_2,
173 >                                                stdin=p1.stdout, stdout=stdout, stderr=self._stderr,
174                                                  universal_newlines=universal_newlines, **self._pipeargs)
175                                  p1.stdout.close()
176                          except Exception as e:
177 <                                self.raise_on_error(actstr_2, str(e))
177 >                                self.raise_on_error(actstr_2, e)
178                          if stdin != PIPE and stdout != PIPE:
179                                  # caller needs to wait after reading or writing (else deadlock)
180                                  res = p1.wait()
# Line 180 | Line 189 | class ProcMixin():
189                                                          % (res, self.qjoin(cmdl_2)))
190                          return p1, p2
191  
183
192          def call_many(self, cmdlines, actstr, _in=None, out=None,
193                          universal_newlines=False):
194                  '''Create a series of N processes, chained via pipes, possibly with an
# Line 200 | Line 208 | class ProcMixin():
208                          # other than direct call_one(), this returns a one-item tuple!
209                          return (self.call_one(cmdlines[0], actstr, _in=_in, out=out,
210                                          universal_newlines=universal_newlines),)
211 <                try: self.__proc_mixin_setup
204 <                except AttributeError: self.__configure_subprocess()
205 <                if _in == PIPE: stdin = _in
206 <                elif isinstance(_in, self._strtypes): stdin = open(_in, 'rb')
207 <                elif hasattr(_in, 'read'): stdin = _in
208 <                else: stdin = self._stdin
209 <                outendstr = '\n'
210 <                if out == PIPE:
211 <                        stdout = out
212 <                elif isinstance(out, self._strtypes):
213 <                        stdout = open(out, 'wb')
214 <                        outendstr = ' > "%s"\n' % out
215 <                elif hasattr(out, 'write'):
216 <                        stdout = out
217 <                        outendstr = ' > "%s"\n' % out.name
218 <                else: stdout = self._stdout
211 >                stdin, stdout, instr, outstr = self.__parse_args(_in, out)
212                  procs = []
213                  if getattr(self, 'verbose', None):
214                          sys.stderr.write('### %s \n' % actstr)
215 <                        sys.stderr.write(self.qjoin(cmdlines[0]) + ' | ')
215 >                        sys.stderr.write(self.qjoin(cmdlines[0]) + instr + ' | ')
216                  if not getattr(self, 'donothing', None):
217                          try:
218                                  prevproc = subprocess.Popen(cmdlines[0], stdin=stdin,
219                                                  stdout=PIPE, stderr=self._stderr, **self._pipeargs)
220                                  procs.append(prevproc)
221                          except Exception as e:
222 <                                self.raise_on_error(actstr, str(e))
222 >                                self.raise_on_error(actstr, e)
223  
224                  for cmdl in cmdlines[1:-1]:
225                          if getattr(self, 'verbose', None):
# Line 239 | Line 232 | class ProcMixin():
232                                          prevproc.stdout.close()
233                                          prevproc = nextproc
234                                  except Exception as e:
235 <                                        self.raise_on_error(actstr, str(e))
235 >                                        self.raise_on_error(actstr, e)
236  
237                  if getattr(self, 'verbose', None):
238 <                        sys.stderr.write(self.qjoin(cmdlines[-1]) + outendstr)
238 >                        sys.stderr.write(self.qjoin(cmdlines[-1]) + outstr + '\n')
239                  if not getattr(self, 'donothing', None):
240                          try:
241                                  lastproc = subprocess.Popen(cmdlines[-1], stdin=prevproc.stdout,
# Line 252 | Line 245 | class ProcMixin():
245                                  procs.append(lastproc)
246                                  prevproc.stdout.close()
247                          except Exception as e:
248 <                                self.raise_on_error(actstr, str(e))
248 >                                self.raise_on_error(actstr, e)
249  
250                          if stdin != PIPE and stdout!= PIPE:
251                                  # caller needs to wait after reading or writing (else deadlock)

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)