summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Harlow <harlowja@gmail.com>2015-01-11 13:03:26 -0800
committerJoshua Harlow <harlowja@yahoo-inc.com>2015-01-12 20:33:51 -0800
commit42a665d06f5a75672417a28375ca4e1988365aa8 (patch)
tree6eee5a7f32668f313ac29c2e45767ae2cbe2f623
parentab71a2677d8ef96c5469efc925d763dde0cd2ea3 (diff)
downloadtaskflow-42a665d06f5a75672417a28375ca4e1988365aa8.tar.gz
Use platform neutral line separator(s)
To at least try to support things like windows it's better if we can make an attempt to use the platform neutral characters for line separator(s) where appropriate. Change-Id: Icc533ed4d4c94f461b7f19600b74146221f17b18
-rw-r--r--taskflow/engines/worker_based/worker.py9
-rw-r--r--taskflow/exceptions.py10
-rw-r--r--taskflow/listeners/claims.py4
-rw-r--r--taskflow/listeners/logging.py3
-rw-r--r--taskflow/types/failure.py8
-rw-r--r--taskflow/types/graph.py3
-rw-r--r--taskflow/types/table.py12
-rw-r--r--taskflow/types/tree.py4
-rw-r--r--taskflow/utils/misc.py5
-rw-r--r--taskflow/utils/persistence_utils.py7
10 files changed, 47 insertions, 18 deletions
diff --git a/taskflow/engines/worker_based/worker.py b/taskflow/engines/worker_based/worker.py
index f75b7a8..5464c81 100644
--- a/taskflow/engines/worker_based/worker.py
+++ b/taskflow/engines/worker_based/worker.py
@@ -141,8 +141,13 @@ class Worker(object):
pass
tpl_params['platform'] = platform.platform()
tpl_params['thread_id'] = tu.get_ident()
- return BANNER_TEMPLATE.substitute(BANNER_TEMPLATE.defaults,
- **tpl_params)
+ banner = BANNER_TEMPLATE.substitute(BANNER_TEMPLATE.defaults,
+ **tpl_params)
+ # NOTE(harlowja): this is needed since the template in this file
+ # will always have newlines that end with '\n' (even on different
+ # platforms due to the way this source file is encoded) so we have
+ # to do this little dance to make it platform neutral...
+ return misc.fix_newlines(banner)
def run(self, display_banner=True, banner_writer=None):
"""Runs the worker."""
diff --git a/taskflow/exceptions.py b/taskflow/exceptions.py
index c663275..d4db4e5 100644
--- a/taskflow/exceptions.py
+++ b/taskflow/exceptions.py
@@ -14,6 +14,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+import os
import traceback
import six
@@ -46,14 +47,19 @@ class TaskFlowException(Exception):
"""Pretty formats a taskflow exception + any connected causes."""
if indent < 0:
raise ValueError("indent must be greater than or equal to zero")
- return "\n".join(self._pformat(self, [], 0,
- indent=indent, indent_text=indent_text))
+ return os.linesep.join(self._pformat(self, [], 0,
+ indent=indent,
+ indent_text=indent_text))
@classmethod
def _pformat(cls, excp, lines, current_indent, indent=2, indent_text=" "):
line_prefix = indent_text * current_indent
for line in traceback.format_exception_only(type(excp), excp):
# We'll add our own newlines on at the end of formatting.
+ #
+ # NOTE(harlowja): the reason we don't search for os.linesep is
+ # that the traceback module seems to only use '\n' (for some
+ # reason).
if line.endswith("\n"):
line = line[0:-1]
lines.append(line_prefix + line)
diff --git a/taskflow/listeners/claims.py b/taskflow/listeners/claims.py
index 7fa8647..82b89cf 100644
--- a/taskflow/listeners/claims.py
+++ b/taskflow/listeners/claims.py
@@ -17,6 +17,7 @@
from __future__ import absolute_import
import logging
+import os
import six
@@ -70,7 +71,8 @@ class CheckingClaimListener(base.Listener):
engine.suspend()
except exceptions.TaskFlowException as e:
LOG.warn("Failed suspending engine '%s', (previously owned by"
- " '%s'):\n%s", engine, self._owner, e.pformat())
+ " '%s'):%s%s", engine, self._owner, os.linesep,
+ e.pformat())
def _flow_receiver(self, state, details):
self._claim_checker(state, details)
diff --git a/taskflow/listeners/logging.py b/taskflow/listeners/logging.py
index c54baf6..4995e9f 100644
--- a/taskflow/listeners/logging.py
+++ b/taskflow/listeners/logging.py
@@ -17,6 +17,7 @@
from __future__ import absolute_import
import logging as logging_base
+import os
import sys
from taskflow.listeners import base
@@ -148,7 +149,7 @@ class DynamicLoggingListener(base.Listener):
# exc_info that can be used but we *should* have a string
# version that we can use instead...
exc_info = None
- exc_details = "\n%s" % fail.pformat(traceback=True)
+ exc_details = "%s%s" % (os.linesep, fail.pformat(traceback=True))
return (exc_info, exc_details)
def _flow_receiver(self, state, details):
diff --git a/taskflow/types/failure.py b/taskflow/types/failure.py
index aba04d4..ae848d3 100644
--- a/taskflow/types/failure.py
+++ b/taskflow/types/failure.py
@@ -15,6 +15,7 @@
# under the License.
import copy
+import os
import sys
import traceback
@@ -280,10 +281,13 @@ class Failure(object):
else:
traceback_str = None
if traceback_str:
- buf.write('\nTraceback (most recent call last):\n')
+ buf.write(os.linesep)
+ buf.write('Traceback (most recent call last):')
+ buf.write(os.linesep)
buf.write(traceback_str)
else:
- buf.write('\nTraceback not available.')
+ buf.write(os.linesep)
+ buf.write('Traceback not available.')
return buf.getvalue()
def __iter__(self):
diff --git a/taskflow/types/graph.py b/taskflow/types/graph.py
index 22b6b71..068a8e2 100644
--- a/taskflow/types/graph.py
+++ b/taskflow/types/graph.py
@@ -15,6 +15,7 @@
# under the License.
import collections
+import os
import networkx as nx
import six
@@ -78,7 +79,7 @@ class DiGraph(nx.DiGraph):
buf.write(" --> %s" % (cycle[i]))
buf.write(" --> %s" % (cycle[0]))
lines.append(" %s" % buf.getvalue())
- return "\n".join(lines)
+ return os.linesep.join(lines)
def export_to_dot(self):
"""Exports the graph to a dot format (requires pydot library)."""
diff --git a/taskflow/types/table.py b/taskflow/types/table.py
index b625720..6813fab 100644
--- a/taskflow/types/table.py
+++ b/taskflow/types/table.py
@@ -15,6 +15,7 @@
# under the License.
import itertools
+import os
import six
@@ -39,6 +40,7 @@ class PleasantTable(object):
COLUMN_SEPARATOR_CHAR = '|'
HEADER_FOOTER_JOINING_CHAR = '+'
HEADER_FOOTER_CHAR = '-'
+ LINE_SEP = os.linesep
@staticmethod
def _center_text(text, max_len, fill=' '):
@@ -87,7 +89,7 @@ class PleasantTable(object):
# Build the main header.
content_buf = six.StringIO()
content_buf.write(header_footer_buf.getvalue())
- content_buf.write("\n")
+ content_buf.write(self.LINE_SEP)
content_buf.write(self.COLUMN_STARTING_CHAR)
for i, header in enumerate(headers):
if i + 1 == column_count:
@@ -99,12 +101,12 @@ class PleasantTable(object):
else:
content_buf.write(headers[i])
content_buf.write(self.COLUMN_SEPARATOR_CHAR)
- content_buf.write("\n")
+ content_buf.write(self.LINE_SEP)
content_buf.write(header_footer_buf.getvalue())
# Build the main content.
row_count = len(self._rows)
if row_count:
- content_buf.write("\n")
+ content_buf.write(self.LINE_SEP)
for i, row in enumerate(self._rows):
pieces = []
for j, column in enumerate(row):
@@ -122,7 +124,7 @@ class PleasantTable(object):
content_buf.write(self.COLUMN_STARTING_CHAR)
content_buf.write(blob)
if i + 1 != row_count:
- content_buf.write("\n")
- content_buf.write("\n")
+ content_buf.write(self.LINE_SEP)
+ content_buf.write(self.LINE_SEP)
content_buf.write(header_footer_buf.getvalue())
return content_buf.getvalue()
diff --git a/taskflow/types/tree.py b/taskflow/types/tree.py
index 6eb960b..e6fad20 100644
--- a/taskflow/types/tree.py
+++ b/taskflow/types/tree.py
@@ -16,6 +16,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+import os
+
import six
@@ -148,7 +150,7 @@ class Node(object):
for i, line in enumerate(_inner_pformat(self, 0)):
accumulator.write(line)
if i < expected_lines:
- accumulator.write('\n')
+ accumulator.write(os.linesep)
return accumulator.getvalue()
def child_count(self, only_direct=True):
diff --git a/taskflow/utils/misc.py b/taskflow/utils/misc.py
index dd3610e..5aa62fd 100644
--- a/taskflow/utils/misc.py
+++ b/taskflow/utils/misc.py
@@ -142,6 +142,11 @@ def clamp(value, minimum, maximum, on_clamped=None):
return value
+def fix_newlines(text, replacement=os.linesep):
+ """Fixes text that *may* end with wrong nl by replacing with right nl."""
+ return replacement.join(text.splitlines())
+
+
def binary_encode(text, encoding='utf-8'):
"""Converts a string of into a binary type using given encoding.
diff --git a/taskflow/utils/persistence_utils.py b/taskflow/utils/persistence_utils.py
index b8a1535..6d5d168 100644
--- a/taskflow/utils/persistence_utils.py
+++ b/taskflow/utils/persistence_utils.py
@@ -15,6 +15,7 @@
# under the License.
import contextlib
+import os
from oslo.utils import timeutils
from oslo.utils import uuidutils
@@ -139,7 +140,7 @@ def pformat_atom_detail(atom_detail, indent=0):
lines.append("%s- failure = %s" % (" " * (indent + 1),
bool(atom_detail.failure)))
lines.extend(_format_meta(atom_detail.meta, indent=indent + 1))
- return "\n".join(lines)
+ return os.linesep.join(lines)
def pformat_flow_detail(flow_detail, indent=0):
@@ -149,7 +150,7 @@ def pformat_flow_detail(flow_detail, indent=0):
lines.extend(_format_meta(flow_detail.meta, indent=indent + 1))
for task_detail in flow_detail:
lines.append(pformat_atom_detail(task_detail, indent=indent + 1))
- return "\n".join(lines)
+ return os.linesep.join(lines)
def pformat(book, indent=0):
@@ -167,4 +168,4 @@ def pformat(book, indent=0):
timeutils.isotime(book.updated_at)))
for flow_detail in book:
lines.append(pformat_flow_detail(flow_detail, indent=indent + 1))
- return "\n".join(lines)
+ return os.linesep.join(lines)