def test(fout=sys.stdout): fout.write("Starting test ...\n") assert hasattr(fout, 'write'), "Input not a file object: " + str(fout) print("\tOpening subprocess (28 Dec 2017):") p = Subprocess('cat', expire_noisily=1) # set to expire noisily... print(p) print("\tOpening bogus subprocess, should fail:") try: # grab stderr just to make sure the error message still appears b = Subprocess('/', 1, expire_noisily=1) assert b.wait(1), 'How is this still alive after 1 sec?' except SubprocessError: print("\t...yep, it failed.") print('\tWrite, then read, two newline-terminated lines, using readline:') p.write('first full line written\n') p.write('second\n') x = p.readline() print(repr(x)) y = p.readline() print(repr(y)) assert x == tobytes('first full line written\n'), 'was: "' + str(x) + '"' assert y == tobytes('second\n'), 'was: "' + str(y) + '"' print('\tThree lines, last sans newline, read using combination:') p.write('first\n') p.write('second\n') p.write('third, (no cr)') print('\tFirst line via readline:') x = p.readline() assert x == tobytes('first\n'), 'was: "' + str(x) + '"' print('\tRest via readPendingChars:') time.sleep(1) # seems like we are sometimes too fast for the subproc y = p.readPendingChars() # Temporarily disable full compliance on this next one. Re-evaluating test # driver in general. But allow to pass here to exercise rest of tests. # assert y == tobytes('second\nthird, (no cr)'), 'was: "'+str(y)+'"' assert y.startswith(tobytes('second\n')), 'was: "' + str(y) + '"' print("\tStopping then continuing subprocess (verbose):") junk = p.readPendingChars( ) # discard any data left over from previous test # verbose stop assert p.stop(1), 'Stop seems to have failed!' print('\tWriting line while subprocess is paused...') p.write('written while subprocess paused\n') print('\tNonblocking read of paused subprocess (should be empty):') x = p.readPendingChars() assert len(x) == 0, 'should have been empty, but had: "' + str(x) + '"' print('\tContinuing subprocess (verbose):') # verbose continue assert p.cont(1), 'Continue seems to have failed! Probably lost subproc...' print('\tReading accumulated line, blocking read:') x = p.readline() assert x == tobytes( 'written while subprocess paused\n'), 'was: "' + str(x) + '"' print("\tDeleting subproc (pid " + str(p.pid) + "), which was to die noisily:") del p print("\tTest Successful!") fout.write("Finished Test Successfully!\n") return True
def test(fout=sys.stdout): fout.write("Starting test ...\n") assert hasattr(fout, 'write'), "Input not a file object: " + str(fout) print("\tOpening subprocess (28 Dec 2017):") p = Subprocess('cat', expire_noisily=1) # set to expire noisily... print(p) print("\tOpening bogus subprocess, should fail:") try: # grab stderr just to make sure the error message still appears b = Subprocess('/', 1, expire_noisily=1) assert b.wait(1), 'How is this still alive after 1 sec?' except SubprocessError: print("\t...yep, it failed.") print('\tWrite, then read, two newline-terminated lines, using readline:') p.write('first full line written\n') p.write('second\n') x = p.readline() print(repr(x)) y = p.readline() print(repr(y)) assert x == tobytes('first full line written\n'), 'was: "'+str(x)+'"' assert y == tobytes('second\n'), 'was: "'+str(y)+'"' print('\tThree lines, last sans newline, read using combination:') p.write('first\n') p.write('second\n') p.write('third, (no cr)') print('\tFirst line via readline:') x = p.readline() assert x == tobytes('first\n'), 'was: "'+str(x)+'"' print('\tRest via readPendingChars:') time.sleep(1) # seems like we are sometimes too fast for the subproc y = p.readPendingChars() # Temporarily disable full compliance on this next one. Re-evaluating test # driver in general. But allow to pass here to exercise rest of tests. # assert y == tobytes('second\nthird, (no cr)'), 'was: "'+str(y)+'"' assert y.startswith(tobytes('second\n')), 'was: "'+str(y)+'"' print("\tStopping then continuing subprocess (verbose):") junk = p.readPendingChars() # discard any data left over from previous test # verbose stop assert p.stop(1), 'Stop seems to have failed!' print('\tWriting line while subprocess is paused...') p.write('written while subprocess paused\n') print('\tNonblocking read of paused subprocess (should be empty):') x = p.readPendingChars() assert len(x) == 0, 'should have been empty, but had: "'+str(x)+'"' print('\tContinuing subprocess (verbose):') # verbose continue assert p.cont(1), 'Continue seems to have failed! Probably lost subproc...' print('\tReading accumulated line, blocking read:') x = p.readline() assert x == tobytes('written while subprocess paused\n'), 'was: "'+str(x)+'"' print("\tDeleting subproc (pid "+str(p.pid)+"), which was to die noisily:") del p print("\tTest Successful!") fout.write("Finished Test Successfully!\n") return True
def pack(self): """Return the WCS in the original IRAF format (in bytes-string)""" init_wcs_sizes() self.commit() wcsStruct = numpy.zeros(_WCS_RECORD_SIZE * WCS_SLOTS, numpy.int16) pad = tobytes('\x00\x00\x00\x00') if _IRAF64BIT: pad = tobytes('\x00\x00\x00\x00\x00\x00\x00\x00') for i in xrange(WCS_SLOTS): x = self.wcs[i] farr = numpy.array(x[:8], numpy.float32) iarr = numpy.array(x[8:11], numpy.int32) if _IRAF64BIT: # see notes in set(); adding 0-padding after every data point lenf = len(farr) # should be 8 farr_rs = farr.reshape(lenf, 1) # turn array into single column farr = numpy.append(farr_rs, numpy.zeros((lenf, 1), numpy.float32), axis=1) farr = farr.flatten() leni = len(iarr) # should be 3 iarr_rs = iarr.reshape(leni, 1) # turn array into single column iarr = numpy.append(iarr_rs, numpy.zeros((leni, 1), numpy.int32), axis=1) iarr = iarr.flatten() # end-pad? if len(farr) + len(iarr) == (_WCS_RECORD_SIZE // 2): pad = BNULLSTR #for IRAF2.14 or prior; all new vers need end-pad # Pack the wcsStruct - this will throw "ValueError: shape mismatch" # if the padding doesn't bring the size out to exactly the # correct length (_WCS_RECORD_SIZE) wcsStruct[_WCS_RECORD_SIZE*i:_WCS_RECORD_SIZE*(i+1)] = \ numpy.fromstring(ndarr2bytes(farr)+ndarr2bytes(iarr)+pad, numpy.int16) return ndarr2bytes(wcsStruct)
def pack(self): """Return the WCS in the original IRAF format (in bytes-string)""" init_wcs_sizes() self.commit() wcsStruct = numpy.zeros(_WCS_RECORD_SIZE*WCS_SLOTS, numpy.int16) pad = tobytes('\x00\x00\x00\x00') if _IRAF64BIT: pad = tobytes('\x00\x00\x00\x00\x00\x00\x00\x00') for i in xrange(WCS_SLOTS): x = self.wcs[i] farr = numpy.array(x[:8],numpy.float32) iarr = numpy.array(x[8:11],numpy.int32) if _IRAF64BIT: # see notes in set(); adding 0-padding after every data point lenf = len(farr) # should be 8 farr_rs = farr.reshape(lenf,1) # turn array into single column farr = numpy.append(farr_rs, numpy.zeros((lenf,1), numpy.float32), axis=1) farr = farr.flatten() leni = len(iarr) # should be 3 iarr_rs = iarr.reshape(leni,1) # turn array into single column iarr = numpy.append(iarr_rs, numpy.zeros((leni,1), numpy.int32), axis=1) iarr = iarr.flatten() # end-pad? if len(farr)+len(iarr) == (_WCS_RECORD_SIZE//2): pad = BNULLSTR #for IRAF2.14 or prior; all new vers need end-pad # Pack the wcsStruct - this will throw "ValueError: shape mismatch" # if the padding doesn't bring the size out to exactly the # correct length (_WCS_RECORD_SIZE) wcsStruct[_WCS_RECORD_SIZE*i:_WCS_RECORD_SIZE*(i+1)] = \ numpy.fromstring(ndarr2bytes(farr)+ndarr2bytes(iarr)+pad, numpy.int16) return ndarr2bytes(wcsStruct)
def write(self, data): """write binary data to IRAF process in blocks of <= 4096 bytes""" i = 0 block = 4096 try: while i < len(data): # Write: # IRAF magic number # number of following bytes # data dsection = data[i:i + block] # the arg parts to the following are all type bytes in PY3K self.process.write(IPC_PREFIX + struct.pack('=h', len(dsection)) + tobytes(dsection)) i = i + block except subproc.SubprocessError, e: raise IrafProcessError("Error in write: %s" % str(e))
def write(self, data): """write binary data to IRAF process in blocks of <= 4096 bytes""" i = 0 block = 4096 try: while i<len(data): # Write: # IRAF magic number # number of following bytes # data dsection = data[i:i+block] # the arg parts to the following are all type bytes in PY3K self.process.write(IPC_PREFIX + struct.pack('=h', len(dsection)) + tobytes(dsection)) i = i + block except subproc.SubprocessError, e: raise IrafProcessError("Error in write: %s" % str(e))
def __doPyobjcWinInit(): """ Initialize the Pyobjc bridging and make some calls to get our PSN and the parent terminal's PSN. Do only ONCE per process. """ # for #108, also see # http://www.fruitstandsoftware.com/blog/2012/08/quick-and-easy-debugging-of-unrecognized-selector-sent-to-instance/ # and # http://www.raywenderlich.com/10209/my-app-crashed-now-what-part-1 global __thisPSN, __termPSN, __screenHeight, __initialized, __objcReqsVoids # Guard against accidental second calls if __initialized: return # Taken in part from PyObjc's Examples/Scripts/wmEnable.py # Be aware that '^' means objc._C_PTR # # input par: n^<argtype> # output par: o^<argtype> # inout par: N^<argtype> # return values are the first in the list, and 'v' is void # OSErr = objc._C_SHT OSStat = objc._C_INT CGErr = objc._C_INT INPSN = tobytes('n^{ProcessSerialNumber=LL}') OUTPSN = tobytes('o^{ProcessSerialNumber=LL}') # OUTPID = tobytes('o^_C_ULNG') # invalid as of objc v3.2 WARPSIG = tobytes('v{CGPoint=ff}') if struct.calcsize("l") > 4: # is 64-bit python WARPSIG = tobytes('v{CGPoint=dd}') FUNCTIONS=[ # These are public API ( u'GetCurrentProcess', OSErr+OUTPSN), ( u'GetFrontProcess', OSErr+OUTPSN), # ( u'GetProcessPID', OSStat+INPSN+OUTPID), # see OUTPID note ( u'SetFrontProcess', OSErr+INPSN), ( u'CGWarpMouseCursorPosition', WARPSIG), ( u'CGMainDisplayID', objc._C_PTR+objc._C_VOID), ( u'CGDisplayPixelsHigh', objc._C_ULNG+objc._C_ULNG), ( u'CGDisplayHideCursor', CGErr+objc._C_ULNG), ( u'CGDisplayShowCursor', CGErr+objc._C_ULNG), # This is undocumented API ( u'CPSSetProcessName', OSErr+INPSN+objc._C_CHARPTR), ( u'CPSEnableForegroundOperation', OSErr+INPSN), ] bndl = AppKit.NSBundle.bundleWithPath_(objc.pathForFramework( u'/System/Library/Frameworks/ApplicationServices.framework')) if bndl is None: raise Exception("Error in aqutil with bundleWithPath_") # Load the functions into the global (module) namespace objc.loadBundleFunctions(bndl, globals(), FUNCTIONS) for (fn, sig) in FUNCTIONS: if fn not in globals(): raise Exception("Not found: "+str(fn)) # Get terminal's PSN (on OSX assume terminal is now frontmost process) # Do this before even setting the PyRAF process to a FG app. # Or use GetProcessInformation w/ __thisPSN, then pinfo.processLauncher if __objcReqsVoids: err, __termPSN = GetFrontProcess(None) else: err, __termPSN = GetFrontProcess() if err: raise Exception("GetFrontProcess: "+str(err)) # Get our PSN # [debug PSN numbers (get pid's) via psn2pid, or use GetProcessPID()] if __objcReqsVoids: err, __thisPSN = GetCurrentProcess(None) else: err, __thisPSN = GetCurrentProcess() if err: raise Exception("GetCurrentProcess: "+str(err)) # Set Proc name err = CPSSetProcessName(__thisPSN, tobytes('PyRAF')) if err: raise Exception("CPSSetProcessName: "+str(err)) # Make us a FG app (need to be in order to use SetFrontProcess on us) # This must be done unless we are called with pythonw. # Apparently the 1010 error is more of a warning... err = CPSEnableForegroundOperation(__thisPSN) if err and err != 1010: raise Exception("CPSEnableForegroundOperation: "+str(err)) # Get the display's absolute height (pixels). # The next line assumes the tkinter root window has already been created # (and withdrawn), but it may have not yet been. # __screenHeight = tkinter._default_root.winfo_screenheight() # So, we will use the less-simple but just as viable CoreGraphics funcs. dispIdPtr = CGMainDisplayID() # no need to keep around? __screenHeight = CGDisplayPixelsHigh(dispIdPtr)