aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Gingrich <david@textio.com>2017-04-11 12:18:31 -0700
committerHolden Karau <holden@us.ibm.com>2017-04-11 12:18:31 -0700
commit6297697f975960a3006c4e58b4964d9ac40eeaf5 (patch)
treefb8e7a38b1fee01fa1b32a346e041f716c4631b0
parent123b4fbbc331f116b45f11b9f7ecbe0b0575323d (diff)
downloadspark-6297697f975960a3006c4e58b4964d9ac40eeaf5.tar.gz
spark-6297697f975960a3006c4e58b4964d9ac40eeaf5.tar.bz2
spark-6297697f975960a3006c4e58b4964d9ac40eeaf5.zip
[SPARK-19505][PYTHON] AttributeError on Exception.message in Python3
## What changes were proposed in this pull request? Added `util._message_exception` helper to use `str(e)` when `e.message` is unavailable (Python3). Grepped for all occurrences of `.message` in `pyspark/` and these were the only occurrences. ## How was this patch tested? - Doctests for helper function ## Legal This is my original work and I license the work to the project under the project’s open source license. Author: David Gingrich <david@textio.com> Closes #16845 from dgingrich/topic-spark-19505-py3-exceptions.
-rw-r--r--dev/sparktestsupport/modules.py1
-rw-r--r--python/pyspark/broadcast.py4
-rw-r--r--python/pyspark/cloudpickle.py9
-rw-r--r--python/pyspark/util.py45
4 files changed, 54 insertions, 5 deletions
diff --git a/dev/sparktestsupport/modules.py b/dev/sparktestsupport/modules.py
index 246f5188a5..78b5b8b0f4 100644
--- a/dev/sparktestsupport/modules.py
+++ b/dev/sparktestsupport/modules.py
@@ -340,6 +340,7 @@ pyspark_core = Module(
"pyspark.profiler",
"pyspark.shuffle",
"pyspark.tests",
+ "pyspark.util",
]
)
diff --git a/python/pyspark/broadcast.py b/python/pyspark/broadcast.py
index 74dee14207..b1b59f73d6 100644
--- a/python/pyspark/broadcast.py
+++ b/python/pyspark/broadcast.py
@@ -21,6 +21,7 @@ import gc
from tempfile import NamedTemporaryFile
from pyspark.cloudpickle import print_exec
+from pyspark.util import _exception_message
if sys.version < '3':
import cPickle as pickle
@@ -82,7 +83,8 @@ class Broadcast(object):
except pickle.PickleError:
raise
except Exception as e:
- msg = "Could not serialize broadcast: " + e.__class__.__name__ + ": " + e.message
+ msg = "Could not serialize broadcast: %s: %s" \
+ % (e.__class__.__name__, _exception_message(e))
print_exec(sys.stderr)
raise pickle.PicklingError(msg)
f.close()
diff --git a/python/pyspark/cloudpickle.py b/python/pyspark/cloudpickle.py
index 959fb8b357..389bee7eee 100644
--- a/python/pyspark/cloudpickle.py
+++ b/python/pyspark/cloudpickle.py
@@ -56,6 +56,7 @@ import dis
import traceback
import weakref
+from pyspark.util import _exception_message
if sys.version < '3':
from pickle import Pickler
@@ -152,13 +153,13 @@ class CloudPickler(Pickler):
except pickle.PickleError:
raise
except Exception as e:
- if "'i' format requires" in e.message:
- msg = "Object too large to serialize: " + e.message
+ emsg = _exception_message(e)
+ if "'i' format requires" in emsg:
+ msg = "Object too large to serialize: %s" % emsg
else:
- msg = "Could not serialize object: " + e.__class__.__name__ + ": " + e.message
+ msg = "Could not serialize object: %s: %s" % (e.__class__.__name__, emsg)
print_exec(sys.stderr)
raise pickle.PicklingError(msg)
-
def save_memoryview(self, obj):
"""Fallback to save_string"""
diff --git a/python/pyspark/util.py b/python/pyspark/util.py
new file mode 100644
index 0000000000..e5d332ce54
--- /dev/null
+++ b/python/pyspark/util.py
@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*-
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+__all__ = []
+
+
+def _exception_message(excp):
+ """Return the message from an exception as either a str or unicode object. Supports both
+ Python 2 and Python 3.
+
+ >>> msg = "Exception message"
+ >>> excp = Exception(msg)
+ >>> msg == _exception_message(excp)
+ True
+
+ >>> msg = u"unicöde"
+ >>> excp = Exception(msg)
+ >>> msg == _exception_message(excp)
+ True
+ """
+ if hasattr(excp, "message"):
+ return excp.message
+ return str(excp)
+
+
+if __name__ == "__main__":
+ import doctest
+ (failure_count, test_count) = doctest.testmod()
+ if failure_count:
+ exit(-1)