beam-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rober...@apache.org
Subject [1/3] incubator-beam git commit: Move Timestamp and related classes into apache_beam/utils.
Date Tue, 01 Nov 2016 05:14:45 GMT
Repository: incubator-beam
Updated Branches:
  refs/heads/python-sdk 979e299c7 -> 13dd9ff49


Move Timestamp and related classes into apache_beam/utils.


Project: http://git-wip-us.apache.org/repos/asf/incubator-beam/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-beam/commit/8fd651f0
Tree: http://git-wip-us.apache.org/repos/asf/incubator-beam/tree/8fd651f0
Diff: http://git-wip-us.apache.org/repos/asf/incubator-beam/diff/8fd651f0

Branch: refs/heads/python-sdk
Commit: 8fd651f05d1e769000fa093e6ab626ef2ac87dec
Parents: 979e299
Author: Robert Bradshaw <robertwb@gmail.com>
Authored: Mon Oct 31 16:47:24 2016 -0700
Committer: Robert Bradshaw <robertwb@gmail.com>
Committed: Mon Oct 31 16:47:24 2016 -0700

----------------------------------------------------------------------
 sdks/python/apache_beam/transforms/timeutil.py  | 197 +----------------
 .../apache_beam/transforms/timeutil_test.py     | 168 --------------
 sdks/python/apache_beam/utils/timestamp.py      | 217 +++++++++++++++++++
 sdks/python/apache_beam/utils/timestamp_test.py | 168 ++++++++++++++
 sdks/python/apache_beam/utils/windowed_value.py |   6 +-
 5 files changed, 394 insertions(+), 362 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/8fd651f0/sdks/python/apache_beam/transforms/timeutil.py
----------------------------------------------------------------------
diff --git a/sdks/python/apache_beam/transforms/timeutil.py b/sdks/python/apache_beam/transforms/timeutil.py
index f026d83..749cda1 100644
--- a/sdks/python/apache_beam/transforms/timeutil.py
+++ b/sdks/python/apache_beam/transforms/timeutil.py
@@ -15,7 +15,7 @@
 # limitations under the License.
 #
 
-"""Time and timer utilities."""
+"""Timestamp utilities."""
 
 from __future__ import absolute_import
 
@@ -25,196 +25,11 @@ from abc import abstractmethod
 import datetime
 
 
-class Timestamp(object):
-  """Represents a Unix second timestamp with microsecond granularity.
-
-  Can be treated in common timestamp arithmetic operations as a numeric type.
-
-  Internally stores a time interval as an int of microseconds. This strategy
-  is necessary since floating point values lose precision when storing values,
-  especially after arithmetic operations (for example, 10000000 % 0.1 evaluates
-  to 0.0999999994448885).
-  """
-
-  def __init__(self, seconds=0, micros=0):
-    self.micros = int(seconds * 1000000) + int(micros)
-
-  @staticmethod
-  def of(seconds):
-    """Return the Timestamp for the given number of seconds.
-
-    If the input is already a Timestamp, the input itself will be returned.
-
-    Args:
-      seconds: Number of seconds as int, float or Timestamp.
-
-    Returns:
-      Corresponding Timestamp object.
-    """
-
-    if isinstance(seconds, Duration):
-      raise TypeError('Can\'t interpret %s as Timestamp.' % seconds)
-    if isinstance(seconds, Timestamp):
-      return seconds
-    return Timestamp(seconds)
-
-  def predecessor(self):
-    """Returns the largest timestamp smaller than self."""
-    return Timestamp(micros=self.micros - 1)
-
-  def __repr__(self):
-    micros = self.micros
-    sign = ''
-    if micros < 0:
-      sign = '-'
-      micros = -micros
-    int_part = micros / 1000000
-    frac_part = micros % 1000000
-    if frac_part:
-      return 'Timestamp(%s%d.%06d)' % (sign, int_part, frac_part)
-    else:
-      return 'Timestamp(%s%d)' % (sign, int_part)
-
-  def to_utc_datetime(self):
-    epoch = datetime.datetime.utcfromtimestamp(0)
-    # We can't easily construct a datetime object from microseconds, so we
-    # create one at the epoch and add an appropriate timedelta interval.
-    return epoch + datetime.timedelta(microseconds=self.micros)
-
-  def isoformat(self):
-    # Append 'Z' for UTC timezone.
-    return self.to_utc_datetime().isoformat() + 'Z'
-
-  def __float__(self):
-    # Note that the returned value may have lost precision.
-    return float(self.micros) / 1000000
-
-  def __int__(self):
-    # Note that the returned value may have lost precision.
-    return self.micros / 1000000
-
-  def __cmp__(self, other):
-    # Allow comparisons between Duration and Timestamp values.
-    if not isinstance(other, Duration):
-      other = Timestamp.of(other)
-    return cmp(self.micros, other.micros)
-
-  def __hash__(self):
-    return hash(self.micros)
-
-  def __add__(self, other):
-    other = Duration.of(other)
-    return Timestamp(micros=self.micros + other.micros)
-
-  def __radd__(self, other):
-    return self + other
-
-  def __sub__(self, other):
-    other = Duration.of(other)
-    return Timestamp(micros=self.micros - other.micros)
-
-  def __mod__(self, other):
-    other = Duration.of(other)
-    return Duration(micros=self.micros % other.micros)
-
-
-MIN_TIMESTAMP = Timestamp(micros=-0x7fffffffffffffff - 1)
-MAX_TIMESTAMP = Timestamp(micros=0x7fffffffffffffff)
-
-
-class Duration(object):
-  """Represents a second duration with microsecond granularity.
-
-  Can be treated in common arithmetic operations as a numeric type.
-
-  Internally stores a time interval as an int of microseconds. This strategy
-  is necessary since floating point values lose precision when storing values,
-  especially after arithmetic operations (for example, 10000000 % 0.1 evaluates
-  to 0.0999999994448885).
-  """
-
-  def __init__(self, seconds=0, micros=0):
-    self.micros = int(seconds * 1000000) + int(micros)
-
-  @staticmethod
-  def of(seconds):
-    """Return the Duration for the given number of seconds since Unix epoch.
-
-    If the input is already a Duration, the input itself will be returned.
-
-    Args:
-      seconds: Number of seconds as int, float or Duration.
-
-    Returns:
-      Corresponding Duration object.
-    """
-
-    if isinstance(seconds, Timestamp):
-      raise TypeError('Can\'t interpret %s as Duration.' % seconds)
-    if isinstance(seconds, Duration):
-      return seconds
-    return Duration(seconds)
-
-  def __repr__(self):
-    micros = self.micros
-    sign = ''
-    if micros < 0:
-      sign = '-'
-      micros = -micros
-    int_part = micros / 1000000
-    frac_part = micros % 1000000
-    if frac_part:
-      return 'Duration(%s%d.%06d)' % (sign, int_part, frac_part)
-    else:
-      return 'Duration(%s%d)' % (sign, int_part)
-
-  def __float__(self):
-    # Note that the returned value may have lost precision.
-    return float(self.micros) / 1000000
-
-  def __int__(self):
-    # Note that the returned value may have lost precision.
-    return self.micros / 1000000
-
-  def __cmp__(self, other):
-    # Allow comparisons between Duration and Timestamp values.
-    if not isinstance(other, Timestamp):
-      other = Duration.of(other)
-    return cmp(self.micros, other.micros)
-
-  def __hash__(self):
-    return hash(self.micros)
-
-  def __neg__(self):
-    return Duration(micros=-self.micros)
-
-  def __add__(self, other):
-    if isinstance(other, Timestamp):
-      return other + self
-    other = Duration.of(other)
-    return Duration(micros=self.micros + other.micros)
-
-  def __radd__(self, other):
-    return self + other
-
-  def __sub__(self, other):
-    other = Duration.of(other)
-    return Duration(micros=self.micros - other.micros)
-
-  def __rsub__(self, other):
-    return -(self - other)
-
-  def __mul__(self, other):
-    other = Duration.of(other)
-    return Duration(micros=self.micros * other.micros / 1000000)
-
-  def __rmul__(self, other):
-    return self * other
-
-  def __mod__(self, other):
-    other = Duration.of(other)
-    return Duration(micros=self.micros % other.micros)
-
+# For backwards compatibility
+from apache_beam.utils.timestamp import Duration
+from apache_beam.utils.timestamp import MAX_TIMESTAMP
+from apache_beam.utils.timestamp import MIN_TIMESTAMP
+from apache_beam.utils.timestamp import Timestamp
 
 class TimeDomain(object):
   """Time domain for streaming timers."""

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/8fd651f0/sdks/python/apache_beam/transforms/timeutil_test.py
----------------------------------------------------------------------
diff --git a/sdks/python/apache_beam/transforms/timeutil_test.py b/sdks/python/apache_beam/transforms/timeutil_test.py
deleted file mode 100644
index a455404..0000000
--- a/sdks/python/apache_beam/transforms/timeutil_test.py
+++ /dev/null
@@ -1,168 +0,0 @@
-#
-# 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.
-#
-
-"""Unit tests for time utilities."""
-
-from __future__ import absolute_import
-
-import unittest
-
-from apache_beam.transforms.timeutil import Duration
-from apache_beam.transforms.timeutil import Timestamp
-
-
-class TimestampTest(unittest.TestCase):
-
-  def test_of(self):
-    interval = Timestamp(123)
-    self.assertEqual(id(interval), id(Timestamp.of(interval)))
-    self.assertEqual(interval, Timestamp.of(123.0))
-    with self.assertRaises(TypeError):
-      Timestamp.of(Duration(10))
-
-  def test_precision(self):
-    self.assertEqual(Timestamp(10000000) % 0.1, 0)
-    self.assertEqual(Timestamp(10000000) % 0.05, 0)
-    self.assertEqual(Timestamp(10000000) % 0.000005, 0)
-    self.assertEqual(Timestamp(10000000) % Duration(0.1), 0)
-    self.assertEqual(Timestamp(10000000) % Duration(0.05), 0)
-    self.assertEqual(Timestamp(10000000) % Duration(0.000005), 0)
-
-  def test_utc_timestamp(self):
-    self.assertEqual(Timestamp(10000000).isoformat(),
-                     '1970-04-26T17:46:40Z')
-    self.assertEqual(Timestamp(10000000.000001).isoformat(),
-                     '1970-04-26T17:46:40.000001Z')
-    self.assertEqual(Timestamp(1458343379.123456).isoformat(),
-                     '2016-03-18T23:22:59.123456Z')
-
-  def test_arithmetic(self):
-    # Supported operations.
-    self.assertEqual(Timestamp(123) + 456, 579)
-    self.assertEqual(Timestamp(123) + Duration(456), 579)
-    self.assertEqual(456 + Timestamp(123), 579)
-    self.assertEqual(Duration(456) + Timestamp(123), 579)
-    self.assertEqual(Timestamp(123) - 456, -333)
-    self.assertEqual(Timestamp(123) - Duration(456), -333)
-    self.assertEqual(Timestamp(1230) % 456, 318)
-    self.assertEqual(Timestamp(1230) % Duration(456), 318)
-
-    # Check that direct comparison of Timestamp and Duration is allowed.
-    self.assertTrue(Duration(123) == Timestamp(123))
-    self.assertTrue(Timestamp(123) == Duration(123))
-    self.assertFalse(Duration(123) == Timestamp(1230))
-    self.assertFalse(Timestamp(123) == Duration(1230))
-
-    # Check return types.
-    self.assertEqual((Timestamp(123) + 456).__class__, Timestamp)
-    self.assertEqual((Timestamp(123) + Duration(456)).__class__, Timestamp)
-    self.assertEqual((456 + Timestamp(123)).__class__, Timestamp)
-    self.assertEqual((Duration(456) + Timestamp(123)).__class__, Timestamp)
-    self.assertEqual((Timestamp(123) - 456).__class__, Timestamp)
-    self.assertEqual((Timestamp(123) - Duration(456)).__class__, Timestamp)
-    self.assertEqual((Timestamp(1230) % 456).__class__, Duration)
-    self.assertEqual((Timestamp(1230) % Duration(456)).__class__, Duration)
-
-    # Unsupported operations.
-    with self.assertRaises(TypeError):
-      self.assertEqual(Timestamp(123) * 456, 56088)
-    with self.assertRaises(TypeError):
-      self.assertEqual(Timestamp(123) * Duration(456), 56088)
-    with self.assertRaises(TypeError):
-      self.assertEqual(456 * Timestamp(123), 56088)
-    with self.assertRaises(TypeError):
-      self.assertEqual(Duration(456) * Timestamp(123), 56088)
-    with self.assertRaises(TypeError):
-      self.assertEqual(456 - Timestamp(123), 333)
-    with self.assertRaises(TypeError):
-      self.assertEqual(Duration(456) - Timestamp(123), 333)
-    with self.assertRaises(TypeError):
-      self.assertEqual(-Timestamp(123), -123)
-    with self.assertRaises(TypeError):
-      self.assertEqual(-Timestamp(123), -Duration(123))
-    with self.assertRaises(TypeError):
-      self.assertEqual(1230 % Timestamp(456), 318)
-    with self.assertRaises(TypeError):
-      self.assertEqual(Duration(1230) % Timestamp(456), 318)
-
-  def test_sort_order(self):
-    self.assertEqual(
-        [-63, Timestamp(-3), 2, 9, Timestamp(292.3), 500],
-        sorted([9, 2, Timestamp(-3), Timestamp(292.3), -63, 500]))
-    self.assertEqual(
-        [4, 5, Timestamp(6), Timestamp(7), 8, 9],
-        sorted([9, 8, Timestamp(7), Timestamp(6), 5, 4]))
-
-  def test_str(self):
-    self.assertEqual('Timestamp(1.234567)',
-                     str(Timestamp(1.234567)))
-    self.assertEqual('Timestamp(-1.234567)',
-                     str(Timestamp(-1.234567)))
-    self.assertEqual('Timestamp(-999999999.900000)',
-                     str(Timestamp(-999999999.9)))
-    self.assertEqual('Timestamp(999999999)',
-                     str(Timestamp(999999999)))
-    self.assertEqual('Timestamp(-999999999)',
-                     str(Timestamp(-999999999)))
-
-
-class DurationTest(unittest.TestCase):
-
-  def test_of(self):
-    interval = Duration(123)
-    self.assertEqual(id(interval), id(Duration.of(interval)))
-    self.assertEqual(interval, Duration.of(123.0))
-    with self.assertRaises(TypeError):
-      Duration.of(Timestamp(10))
-
-  def test_precision(self):
-    self.assertEqual(Duration(10000000) % 0.1, 0)
-    self.assertEqual(Duration(10000000) % 0.05, 0)
-    self.assertEqual(Duration(10000000) % 0.000005, 0)
-
-  def test_arithmetic(self):
-    self.assertEqual(Duration(123) + 456, 579)
-    self.assertEqual(456 + Duration(123), 579)
-    self.assertEqual(Duration(123) * 456, 56088)
-    self.assertEqual(456 * Duration(123), 56088)
-    self.assertEqual(Duration(123) - 456, -333)
-    self.assertEqual(456 - Duration(123), 333)
-    self.assertEqual(-Duration(123), -123)
-
-  def test_sort_order(self):
-    self.assertEqual(
-        [-63, Duration(-3), 2, 9, Duration(292.3), 500],
-        sorted([9, 2, Duration(-3), Duration(292.3), -63, 500]))
-    self.assertEqual(
-        [4, 5, Duration(6), Duration(7), 8, 9],
-        sorted([9, 8, Duration(7), Duration(6), 5, 4]))
-
-  def test_str(self):
-    self.assertEqual('Duration(1.234567)',
-                     str(Duration(1.234567)))
-    self.assertEqual('Duration(-1.234567)',
-                     str(Duration(-1.234567)))
-    self.assertEqual('Duration(-999999999.900000)',
-                     str(Duration(-999999999.9)))
-    self.assertEqual('Duration(999999999)',
-                     str(Duration(999999999)))
-    self.assertEqual('Duration(-999999999)',
-                     str(Duration(-999999999)))
-
-
-if __name__ == '__main__':
-  unittest.main()

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/8fd651f0/sdks/python/apache_beam/utils/timestamp.py
----------------------------------------------------------------------
diff --git a/sdks/python/apache_beam/utils/timestamp.py b/sdks/python/apache_beam/utils/timestamp.py
new file mode 100644
index 0000000..1a019c3
--- /dev/null
+++ b/sdks/python/apache_beam/utils/timestamp.py
@@ -0,0 +1,217 @@
+#
+# 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.
+#
+
+"""Timestamp utilities."""
+
+from __future__ import absolute_import
+
+from abc import ABCMeta
+from abc import abstractmethod
+
+import datetime
+
+
+class Timestamp(object):
+  """Represents a Unix second timestamp with microsecond granularity.
+
+  Can be treated in common timestamp arithmetic operations as a numeric type.
+
+  Internally stores a time interval as an int of microseconds. This strategy
+  is necessary since floating point values lose precision when storing values,
+  especially after arithmetic operations (for example, 10000000 % 0.1 evaluates
+  to 0.0999999994448885).
+  """
+
+  def __init__(self, seconds=0, micros=0):
+    self.micros = int(seconds * 1000000) + int(micros)
+
+  @staticmethod
+  def of(seconds):
+    """Return the Timestamp for the given number of seconds.
+
+    If the input is already a Timestamp, the input itself will be returned.
+
+    Args:
+      seconds: Number of seconds as int, float or Timestamp.
+
+    Returns:
+      Corresponding Timestamp object.
+    """
+
+    if isinstance(seconds, Duration):
+      raise TypeError('Can\'t interpret %s as Timestamp.' % seconds)
+    if isinstance(seconds, Timestamp):
+      return seconds
+    return Timestamp(seconds)
+
+  def predecessor(self):
+    """Returns the largest timestamp smaller than self."""
+    return Timestamp(micros=self.micros - 1)
+
+  def __repr__(self):
+    micros = self.micros
+    sign = ''
+    if micros < 0:
+      sign = '-'
+      micros = -micros
+    int_part = micros / 1000000
+    frac_part = micros % 1000000
+    if frac_part:
+      return 'Timestamp(%s%d.%06d)' % (sign, int_part, frac_part)
+    else:
+      return 'Timestamp(%s%d)' % (sign, int_part)
+
+  def to_utc_datetime(self):
+    epoch = datetime.datetime.utcfromtimestamp(0)
+    # We can't easily construct a datetime object from microseconds, so we
+    # create one at the epoch and add an appropriate timedelta interval.
+    return epoch + datetime.timedelta(microseconds=self.micros)
+
+  def isoformat(self):
+    # Append 'Z' for UTC timezone.
+    return self.to_utc_datetime().isoformat() + 'Z'
+
+  def __float__(self):
+    # Note that the returned value may have lost precision.
+    return float(self.micros) / 1000000
+
+  def __int__(self):
+    # Note that the returned value may have lost precision.
+    return self.micros / 1000000
+
+  def __cmp__(self, other):
+    # Allow comparisons between Duration and Timestamp values.
+    if not isinstance(other, Duration):
+      other = Timestamp.of(other)
+    return cmp(self.micros, other.micros)
+
+  def __hash__(self):
+    return hash(self.micros)
+
+  def __add__(self, other):
+    other = Duration.of(other)
+    return Timestamp(micros=self.micros + other.micros)
+
+  def __radd__(self, other):
+    return self + other
+
+  def __sub__(self, other):
+    other = Duration.of(other)
+    return Timestamp(micros=self.micros - other.micros)
+
+  def __mod__(self, other):
+    other = Duration.of(other)
+    return Duration(micros=self.micros % other.micros)
+
+
+MIN_TIMESTAMP = Timestamp(micros=-0x7fffffffffffffff - 1)
+MAX_TIMESTAMP = Timestamp(micros=0x7fffffffffffffff)
+
+
+class Duration(object):
+  """Represents a second duration with microsecond granularity.
+
+  Can be treated in common arithmetic operations as a numeric type.
+
+  Internally stores a time interval as an int of microseconds. This strategy
+  is necessary since floating point values lose precision when storing values,
+  especially after arithmetic operations (for example, 10000000 % 0.1 evaluates
+  to 0.0999999994448885).
+  """
+
+  def __init__(self, seconds=0, micros=0):
+    self.micros = int(seconds * 1000000) + int(micros)
+
+  @staticmethod
+  def of(seconds):
+    """Return the Duration for the given number of seconds since Unix epoch.
+
+    If the input is already a Duration, the input itself will be returned.
+
+    Args:
+      seconds: Number of seconds as int, float or Duration.
+
+    Returns:
+      Corresponding Duration object.
+    """
+
+    if isinstance(seconds, Timestamp):
+      raise TypeError('Can\'t interpret %s as Duration.' % seconds)
+    if isinstance(seconds, Duration):
+      return seconds
+    return Duration(seconds)
+
+  def __repr__(self):
+    micros = self.micros
+    sign = ''
+    if micros < 0:
+      sign = '-'
+      micros = -micros
+    int_part = micros / 1000000
+    frac_part = micros % 1000000
+    if frac_part:
+      return 'Duration(%s%d.%06d)' % (sign, int_part, frac_part)
+    else:
+      return 'Duration(%s%d)' % (sign, int_part)
+
+  def __float__(self):
+    # Note that the returned value may have lost precision.
+    return float(self.micros) / 1000000
+
+  def __int__(self):
+    # Note that the returned value may have lost precision.
+    return self.micros / 1000000
+
+  def __cmp__(self, other):
+    # Allow comparisons between Duration and Timestamp values.
+    if not isinstance(other, Timestamp):
+      other = Duration.of(other)
+    return cmp(self.micros, other.micros)
+
+  def __hash__(self):
+    return hash(self.micros)
+
+  def __neg__(self):
+    return Duration(micros=-self.micros)
+
+  def __add__(self, other):
+    if isinstance(other, Timestamp):
+      return other + self
+    other = Duration.of(other)
+    return Duration(micros=self.micros + other.micros)
+
+  def __radd__(self, other):
+    return self + other
+
+  def __sub__(self, other):
+    other = Duration.of(other)
+    return Duration(micros=self.micros - other.micros)
+
+  def __rsub__(self, other):
+    return -(self - other)
+
+  def __mul__(self, other):
+    other = Duration.of(other)
+    return Duration(micros=self.micros * other.micros / 1000000)
+
+  def __rmul__(self, other):
+    return self * other
+
+  def __mod__(self, other):
+    other = Duration.of(other)
+    return Duration(micros=self.micros % other.micros)
+

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/8fd651f0/sdks/python/apache_beam/utils/timestamp_test.py
----------------------------------------------------------------------
diff --git a/sdks/python/apache_beam/utils/timestamp_test.py b/sdks/python/apache_beam/utils/timestamp_test.py
new file mode 100644
index 0000000..3322936
--- /dev/null
+++ b/sdks/python/apache_beam/utils/timestamp_test.py
@@ -0,0 +1,168 @@
+#
+# 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.
+#
+
+"""Unit tests for time utilities."""
+
+from __future__ import absolute_import
+
+import unittest
+
+from apache_beam.utils.timestamp import Duration
+from apache_beam.utils.timestamp import Timestamp
+
+
+class TimestampTest(unittest.TestCase):
+
+  def test_of(self):
+    interval = Timestamp(123)
+    self.assertEqual(id(interval), id(Timestamp.of(interval)))
+    self.assertEqual(interval, Timestamp.of(123.0))
+    with self.assertRaises(TypeError):
+      Timestamp.of(Duration(10))
+
+  def test_precision(self):
+    self.assertEqual(Timestamp(10000000) % 0.1, 0)
+    self.assertEqual(Timestamp(10000000) % 0.05, 0)
+    self.assertEqual(Timestamp(10000000) % 0.000005, 0)
+    self.assertEqual(Timestamp(10000000) % Duration(0.1), 0)
+    self.assertEqual(Timestamp(10000000) % Duration(0.05), 0)
+    self.assertEqual(Timestamp(10000000) % Duration(0.000005), 0)
+
+  def test_utc_timestamp(self):
+    self.assertEqual(Timestamp(10000000).isoformat(),
+                     '1970-04-26T17:46:40Z')
+    self.assertEqual(Timestamp(10000000.000001).isoformat(),
+                     '1970-04-26T17:46:40.000001Z')
+    self.assertEqual(Timestamp(1458343379.123456).isoformat(),
+                     '2016-03-18T23:22:59.123456Z')
+
+  def test_arithmetic(self):
+    # Supported operations.
+    self.assertEqual(Timestamp(123) + 456, 579)
+    self.assertEqual(Timestamp(123) + Duration(456), 579)
+    self.assertEqual(456 + Timestamp(123), 579)
+    self.assertEqual(Duration(456) + Timestamp(123), 579)
+    self.assertEqual(Timestamp(123) - 456, -333)
+    self.assertEqual(Timestamp(123) - Duration(456), -333)
+    self.assertEqual(Timestamp(1230) % 456, 318)
+    self.assertEqual(Timestamp(1230) % Duration(456), 318)
+
+    # Check that direct comparison of Timestamp and Duration is allowed.
+    self.assertTrue(Duration(123) == Timestamp(123))
+    self.assertTrue(Timestamp(123) == Duration(123))
+    self.assertFalse(Duration(123) == Timestamp(1230))
+    self.assertFalse(Timestamp(123) == Duration(1230))
+
+    # Check return types.
+    self.assertEqual((Timestamp(123) + 456).__class__, Timestamp)
+    self.assertEqual((Timestamp(123) + Duration(456)).__class__, Timestamp)
+    self.assertEqual((456 + Timestamp(123)).__class__, Timestamp)
+    self.assertEqual((Duration(456) + Timestamp(123)).__class__, Timestamp)
+    self.assertEqual((Timestamp(123) - 456).__class__, Timestamp)
+    self.assertEqual((Timestamp(123) - Duration(456)).__class__, Timestamp)
+    self.assertEqual((Timestamp(1230) % 456).__class__, Duration)
+    self.assertEqual((Timestamp(1230) % Duration(456)).__class__, Duration)
+
+    # Unsupported operations.
+    with self.assertRaises(TypeError):
+      self.assertEqual(Timestamp(123) * 456, 56088)
+    with self.assertRaises(TypeError):
+      self.assertEqual(Timestamp(123) * Duration(456), 56088)
+    with self.assertRaises(TypeError):
+      self.assertEqual(456 * Timestamp(123), 56088)
+    with self.assertRaises(TypeError):
+      self.assertEqual(Duration(456) * Timestamp(123), 56088)
+    with self.assertRaises(TypeError):
+      self.assertEqual(456 - Timestamp(123), 333)
+    with self.assertRaises(TypeError):
+      self.assertEqual(Duration(456) - Timestamp(123), 333)
+    with self.assertRaises(TypeError):
+      self.assertEqual(-Timestamp(123), -123)
+    with self.assertRaises(TypeError):
+      self.assertEqual(-Timestamp(123), -Duration(123))
+    with self.assertRaises(TypeError):
+      self.assertEqual(1230 % Timestamp(456), 318)
+    with self.assertRaises(TypeError):
+      self.assertEqual(Duration(1230) % Timestamp(456), 318)
+
+  def test_sort_order(self):
+    self.assertEqual(
+        [-63, Timestamp(-3), 2, 9, Timestamp(292.3), 500],
+        sorted([9, 2, Timestamp(-3), Timestamp(292.3), -63, 500]))
+    self.assertEqual(
+        [4, 5, Timestamp(6), Timestamp(7), 8, 9],
+        sorted([9, 8, Timestamp(7), Timestamp(6), 5, 4]))
+
+  def test_str(self):
+    self.assertEqual('Timestamp(1.234567)',
+                     str(Timestamp(1.234567)))
+    self.assertEqual('Timestamp(-1.234567)',
+                     str(Timestamp(-1.234567)))
+    self.assertEqual('Timestamp(-999999999.900000)',
+                     str(Timestamp(-999999999.9)))
+    self.assertEqual('Timestamp(999999999)',
+                     str(Timestamp(999999999)))
+    self.assertEqual('Timestamp(-999999999)',
+                     str(Timestamp(-999999999)))
+
+
+class DurationTest(unittest.TestCase):
+
+  def test_of(self):
+    interval = Duration(123)
+    self.assertEqual(id(interval), id(Duration.of(interval)))
+    self.assertEqual(interval, Duration.of(123.0))
+    with self.assertRaises(TypeError):
+      Duration.of(Timestamp(10))
+
+  def test_precision(self):
+    self.assertEqual(Duration(10000000) % 0.1, 0)
+    self.assertEqual(Duration(10000000) % 0.05, 0)
+    self.assertEqual(Duration(10000000) % 0.000005, 0)
+
+  def test_arithmetic(self):
+    self.assertEqual(Duration(123) + 456, 579)
+    self.assertEqual(456 + Duration(123), 579)
+    self.assertEqual(Duration(123) * 456, 56088)
+    self.assertEqual(456 * Duration(123), 56088)
+    self.assertEqual(Duration(123) - 456, -333)
+    self.assertEqual(456 - Duration(123), 333)
+    self.assertEqual(-Duration(123), -123)
+
+  def test_sort_order(self):
+    self.assertEqual(
+        [-63, Duration(-3), 2, 9, Duration(292.3), 500],
+        sorted([9, 2, Duration(-3), Duration(292.3), -63, 500]))
+    self.assertEqual(
+        [4, 5, Duration(6), Duration(7), 8, 9],
+        sorted([9, 8, Duration(7), Duration(6), 5, 4]))
+
+  def test_str(self):
+    self.assertEqual('Duration(1.234567)',
+                     str(Duration(1.234567)))
+    self.assertEqual('Duration(-1.234567)',
+                     str(Duration(-1.234567)))
+    self.assertEqual('Duration(-999999999.900000)',
+                     str(Duration(-999999999.9)))
+    self.assertEqual('Duration(999999999)',
+                     str(Duration(999999999)))
+    self.assertEqual('Duration(-999999999)',
+                     str(Duration(-999999999)))
+
+
+if __name__ == '__main__':
+  unittest.main()

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/8fd651f0/sdks/python/apache_beam/utils/windowed_value.py
----------------------------------------------------------------------
diff --git a/sdks/python/apache_beam/utils/windowed_value.py b/sdks/python/apache_beam/utils/windowed_value.py
index 4c50e72..35cc52f 100644
--- a/sdks/python/apache_beam/utils/windowed_value.py
+++ b/sdks/python/apache_beam/utils/windowed_value.py
@@ -25,9 +25,9 @@
 
 #cython: profile=True
 
-from apache_beam.transforms.timeutil import MAX_TIMESTAMP
-from apache_beam.transforms.timeutil import MIN_TIMESTAMP
-from apache_beam.transforms.timeutil import Timestamp
+from apache_beam.utils.timestamp import MAX_TIMESTAMP
+from apache_beam.utils.timestamp import MIN_TIMESTAMP
+from apache_beam.utils.timestamp import Timestamp
 
 
 class WindowedValue(object):


Mime
View raw message