Skip to content

Commit

Permalink
|\ merge from release-0.7.2.1, released as 0.7.2.
Browse files Browse the repository at this point in the history
  • Loading branch information
StyXman committed Feb 26, 2016
2 parents 670c526 + ad1ee58 commit a7caaa1
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 41 deletions.
18 changes: 12 additions & 6 deletions ChangeLog.rst
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
ayrton (0.7.2) UNRELEASED; urgency=medium
ayrton (0.7.2.1) unstable; urgency=medium

* Fix running remote tests with other versions of python.
* Fix tests borken by a change in `ls`'s output.
* Fix iterating over the long output of a command à la `for line in foo(...): ...`. Currently you must add `_bg=True` to the execution options.
* Fix recognizing names bound by for loops.
* Fix iterating over the log ouput of a `Command` in synchronous mode (that is, not running in the `_bg`). This complements the fix in the previous release.

-- Marcos Dione <[email protected]> Fri, 26 Feb 2016 13:54:46 +0100

ayrton (0.7.2) unstable; urgency=medium

* Fix running remote tests with other versions of Python.
* Fix tests broken by a change in `ls`'s output.
* Fix iterating over the long output of a `Command` à la `for line in foo(...): ...`. Currently you must add `_bg=True` to the execution options.
* Fix recognizing names bound by `for` loops.
* Added options `-d|--debug`, `-dd|--debug2` and `-ddd|--debug3` for enabling debug logs.
* Added option `-xxx|--trace-all` for tracing all python execution. Use with caution, it generates lots of output.

-- Marcos Dione <[email protected]> Thu, 25 Feb 2016 12:40:04 +0100
-- Marcos Dione <[email protected]> Thu, 25 Feb 2016 13:09:08 +0100

ayrton (0.7.1) unstable; urgency=medium

Expand Down
2 changes: 1 addition & 1 deletion ayrton/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def debug (level=logging.DEBUG, filename='ayrton.log'):
from ayrton.parser.astcompiler.astbuilder import ast_from_node
from ayrton.ast_pprinter import pprint

__version__= '0.7.2'
__version__= '0.7.2.1'


class ExecParams:
Expand Down
93 changes: 63 additions & 30 deletions ayrton/execute.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ class Command:
supported_options= ('_in', '_out', '_err', '_end', '_chomp', '_encoding',
'_env', '_bg', '_fails')


def __init__ (self, path):
self.path= path
self.exe= resolve_program (path)
Expand All @@ -126,9 +127,11 @@ def __init__ (self, path):

self._exit_code= None
self.capture_file= None
self.captured_lines= None

self.child_pid= None


def prepare_fds (self):
if '_in' in self.options:
i= self.options['_in']
Expand Down Expand Up @@ -204,6 +207,7 @@ def prepare_fds (self):

logger.debug ("stderr_pipe: %s", self.stderr_pipe)


def child (self):
logger.debug ('child')

Expand Down Expand Up @@ -360,6 +364,7 @@ def prepare_args (self, cmd, args, kwargs):

return ans


def prepare_arg (self, seq, name, value):
if value!=False:
if isiterable (value):
Expand Down Expand Up @@ -410,6 +415,14 @@ def parent (self):
# command to exit with a non-zero status, or zero if all commands exit
# successfully.
if not self.options['_bg']:
if self.options.get ('_out', None)==Capture:
# if we don't do this, a program with lots of output freezes
# when its output buffer is full
# on the other hand, this might take a lot of memory
# but it's the same as in foo=$(long_output)
self.prepare_capture_file ()
self.captured_lines= self.capture_file.readlines ()

self.wait ()
# NOTE: uhm?
ayrton.runner.wait_for_pending_children ()
Expand All @@ -419,17 +432,19 @@ def parent (self):

def wait (self):
logger.debug (self.child_pid)
self._exit_code= os.waitpid (self.child_pid, 0)[1] >> 8

if self._exit_code==127:
# NOTE: when running bash, it returns 127 when it can't find the script to run
raise CommandNotFound (self.path)
if self._exit_code is None:
self._exit_code= os.waitpid (self.child_pid, 0)[1] >> 8

if self._exit_code==127:
# NOTE: when running bash, it returns 127 when it can't find the script to run
raise CommandNotFound (self.path)

if (ayrton.runner.options.get ('errexit', False) and
self._exit_code!=0 and
not self.options.get ('_fails', False)):
if (ayrton.runner.options.get ('errexit', False) and
self._exit_code!=0 and
not self.options.get ('_fails', False)):

raise CommandFailed (self)
raise CommandFailed (self)


def exit_code (self):
Expand Down Expand Up @@ -460,6 +475,7 @@ def __call__ (self, *args, **kwargs):
self.stdout_pipe= None
self.stderr_pipe= None

# TODO: why this again here? see __init__()
self._exit_code= None
self.capture_file= None

Expand Down Expand Up @@ -510,60 +526,77 @@ def prepare_capture_file (self):


def __str__ (self):
if self._exit_code is None:
self.wait ()
self.wait ()

self.prepare_capture_file ()
if self.captured_lines:
s= ''.join (self.captured_lines)
else:
self.prepare_capture_file ()
s= self.capture_file.read ()

return self.capture_file.read ()
return s


def __iter__ (self):
logger.debug ('iterating!')

self.prepare_capture_file ()
if self.captured_lines:
for line in self.captured_lines:
# while iterating we always remove the trailing \n
line= line.rstrip (os.linesep)
yield line
else:
self.prepare_capture_file ()

if self.capture_file is not None:
for line in self.capture_file.readlines ():
if self.options['_chomp']:
line= line.rstrip (os.linesep)
# while iterating we always remove the trailing \n
line= line.rstrip (os.linesep)

logger.debug2 ('read line: %s', line)
yield line

# finish him!
logger.debug ('finished!')
self.capture_file.close ()
if self._exit_code is None:
self.wait ()
else:
logger.debug ('dunno what to do!')
# if we're iterating, then the Command is in _bg
self.wait ()


def readlines (self):
if self._exit_code is None:
self.wait ()
self.wait ()

if self.captured_lines:
lines= self.captured_lines
else:
self.prepare_capture_file ()
lines= self.capture_file.readlines ()
self.capture_file.close ()

return lines

# ugly way to not leak the file()
return ( line for line in self )

# BUG this method is leaking an opened file()
# self.capture_file
def readline (self):
if self._exit_code is None:
self.wait ()
self.wait ()

if self.captured_lines:
line= self.captured_lines.pop (0)
else:
self.prepare_capture_file ()
line= self.capture_file.readline ()

self.prepare_capture_file ()
line= self.capture_file.readline ()
if self.options['_chomp']:
line= line.rstrip (os.linesep)

return line


def close (self):
if self._exit_code is None:
self.wait ()
self.wait ()
self.capture_file.close ()


def __del__ (self):
# finish it
if self._exit_code is None and self.child_pid is not None:
Expand Down
2 changes: 1 addition & 1 deletion ayrton/tests/scripts/testShortIter.ay
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#! /usr/bin/env ayrton

for line in echo ('yes!'):
for line in echo ('yes!', _bg=True):
ayrton_return_value= line.strip ()
8 changes: 6 additions & 2 deletions ayrton/tests/test_ayrton.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,17 +385,21 @@ def testComposing (self):
def testBg (self):
'''This test takes some time...'''
self.doTest ('testBg.ay', 'yes!')
# the tests script does not wait for find to finish
# so we do it here
self.runner.wait_for_pending_children ()

def testShortIter (self):
'''This test takes some time...'''
self.doTest ('testShortIter.ay', 'yes!')
self.runner.wait_for_pending_children ()

def testLongIter (self):
'''This test takes some time...'''
self.doTest ('testLongIter.ay', 'yes!')
self.runner.wait_for_pending_children ()

def testLongOutput (self):
'''This test takes some time...'''
self.doTest ('testLongOutput.ay', 'yes!')

class CommandDetection (ScriptExecution):

Expand Down
2 changes: 1 addition & 1 deletion ayrton/tests/test_execute.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ def testOutAsIterable (self):
text= '_out=Capture'
a= echo (text, _out=Capture)
for i in a:
# notice that here there's no \n
# NOTE: that here there's no \n!
self.assertEqual (i, text)

def testOutAsFd (self):
Expand Down
6 changes: 6 additions & 0 deletions release.ay
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ import ayrton
option ('-e')

if make ('tests'):
# with remote ('mustang'):
# cd (bash ('~/src/projects/ayrton'))
# git ('pull', 'devel')
# # if this fails, hopefully the whole script stops :)
# make ('tests')

# this command might fail if it wants to
uncommited= git ('status', --short=True) | grep ('^ M', _out=Capture, _fails=True)
if uncommited:
Expand Down

0 comments on commit a7caaa1

Please sign in to comment.