Matt Behrens avatar Matt Behrens committed d4be47e

tz-aware datetimes for timestamp constructor; no tests yet

Comments (0)

Files changed (8)

lib/yaml/__init__.py

     finally:
         loader.dispose()
 
-def load(stream, Loader=Loader):
+def load(stream, Loader=Loader, tz_aware_datetimes=False):
     """
     Parse the first YAML document in a stream
     and produce the corresponding Python object.
     """
-    loader = Loader(stream)
+    try:
+        loader = Loader(stream, tz_aware_datetimes=tz_aware_datetimes)
+    except TypeError:
+        loader = Loader(stream)
     try:
         return loader.get_single_data()
     finally:
         loader.dispose()
 
-def load_all(stream, Loader=Loader):
+def load_all(stream, Loader=Loader, tz_aware_datetimes=False):
     """
     Parse all YAML documents in a stream
     and produce corresponding Python objects.
     """
-    loader = Loader(stream)
+    try:
+        loader = Loader(stream, tz_aware_datetimes=tz_aware_datetimes)
+    except TypeError:
+        loader = Loader(stream)
     try:
         while loader.check_data():
             yield loader.get_data()
     finally:
         loader.dispose()
 
-def safe_load(stream):
+def safe_load(stream, tz_aware_datetimes=False):
     """
     Parse the first YAML document in a stream
     and produce the corresponding Python object.
     Resolve only basic YAML tags.
     """
-    return load(stream, SafeLoader)
+    return load(stream, SafeLoader, tz_aware_datetimes=tz_aware_datetimes)
 
-def safe_load_all(stream):
+def safe_load_all(stream, tz_aware_datetimes=False):
     """
     Parse all YAML documents in a stream
     and produce corresponding Python objects.
     Resolve only basic YAML tags.
     """
-    return load_all(stream, SafeLoader)
+    return load_all(stream, SafeLoader, tz_aware_datetimes=tz_aware_datetimes)
 
 def emit(events, stream=None, Dumper=Dumper,
         canonical=None, indent=None, width=None,

lib/yaml/constructor.py

 
 import binascii, re, sys, types
 
+class FixedOffset(datetime.tzinfo):
+    def __init__(self, delta, name):
+        self.delta = delta
+        self.name = name
+
+    def utcoffset(self, dt):
+        return self.delta
+
+    def tzname(self, dt):
+        return self.name
+
+    def dst(self, dt):
+        return datetime.timedelta(0)
+
+    def __repr__(self):
+        return '<%s %s>' % (self.__class__.__name__, self.name)
+
+UTC = FixedOffset(datetime.timedelta(0), 'UTC')
+
 class ConstructorError(MarkedYAMLError):
     pass
 
 
 class SafeConstructor(BaseConstructor):
 
+    def __init__(self, tz_aware_datetimes=False):
+        BaseConstructor.__init__(self)
+        self.tz_aware_datetimes = tz_aware_datetimes
+
     def construct_scalar(self, node):
         if isinstance(node, MappingNode):
             for key_node, value_node in node.value:
         month = int(values['month'])
         day = int(values['day'])
         if not values['hour']:
-            return datetime.date(year, month, day)
+            if self.tz_aware_datetimes:
+                return datetime.datetime(year, month, day, 0, 0, 0, tzinfo=UTC)
+            else:
+                return datetime.date(year, month, day)
         hour = int(values['hour'])
         minute = int(values['minute'])
         second = int(values['second'])
             delta = datetime.timedelta(hours=tz_hour, minutes=tz_minute)
             if values['tz_sign'] == '-':
                 delta = -delta
-        data = datetime.datetime(year, month, day, hour, minute, second, fraction)
-        if delta:
-            data -= delta
-        return data
+            if self.tz_aware_datetimes:
+                tz_name = '%s%02d:%02d' % (values['tz_sign'],
+                                           tz_hour, tz_minute)
+                return datetime.datetime(year, month, day,
+                                         hour, minute, second, fraction,
+                                         tzinfo=FixedOffset(delta, tz_name))
+            else:
+                return (datetime.datetime(year, month, day,
+                                          hour, minute, second, fraction) -
+                        delta)
+        else:
+            if self.tz_aware_datetimes:
+                return datetime.datetime(year, month, day,
+                                         hour, minute, second, fraction,
+                                         tzinfo=UTC)
+            else:
+                return datetime.datetime(year, month, day,
+                                         hour, minute, second, fraction)
 
     def construct_yaml_omap(self, node):
         # Note: we do not check for duplicate keys, because it's too

lib/yaml/cyaml.py

 
 class CBaseLoader(CParser, BaseConstructor, BaseResolver):
 
-    def __init__(self, stream):
+    def __init__(self, stream, tz_aware_datetimes=False):
         CParser.__init__(self, stream)
         BaseConstructor.__init__(self)
         BaseResolver.__init__(self)
 
 class CSafeLoader(CParser, SafeConstructor, Resolver):
 
-    def __init__(self, stream):
+    def __init__(self, stream, tz_aware_datetimes=False):
         CParser.__init__(self, stream)
-        SafeConstructor.__init__(self)
+        SafeConstructor.__init__(self, tz_aware_datetimes=tz_aware_datetimes)
         Resolver.__init__(self)
 
 class CLoader(CParser, Constructor, Resolver):
 
-    def __init__(self, stream):
+    def __init__(self, stream, tz_aware_datetimes=False):
         CParser.__init__(self, stream)
-        Constructor.__init__(self)
+        Constructor.__init__(self, tz_aware_datetimes=tz_aware_datetimes)
         Resolver.__init__(self)
 
 class CBaseDumper(CEmitter, BaseRepresenter, BaseResolver):

lib/yaml/loader.py

 
 class BaseLoader(Reader, Scanner, Parser, Composer, BaseConstructor, BaseResolver):
 
-    def __init__(self, stream):
+    def __init__(self, stream, tz_aware_datetimes=False):
         Reader.__init__(self, stream)
         Scanner.__init__(self)
         Parser.__init__(self)
 
 class SafeLoader(Reader, Scanner, Parser, Composer, SafeConstructor, Resolver):
 
-    def __init__(self, stream):
+    def __init__(self, stream, tz_aware_datetimes=False):
         Reader.__init__(self, stream)
         Scanner.__init__(self)
         Parser.__init__(self)
         Composer.__init__(self)
-        SafeConstructor.__init__(self)
+        SafeConstructor.__init__(self, tz_aware_datetimes)
         Resolver.__init__(self)
 
 class Loader(Reader, Scanner, Parser, Composer, Constructor, Resolver):
 
-    def __init__(self, stream):
+    def __init__(self, stream, tz_aware_datetimes=False):
         Reader.__init__(self, stream)
         Scanner.__init__(self)
         Parser.__init__(self)
         Composer.__init__(self)
-        Constructor.__init__(self)
+        Constructor.__init__(self, tz_aware_datetimes)
         Resolver.__init__(self)
 

lib3/yaml/__init__.py

     finally:
         loader.dispose()
 
-def load(stream, Loader=Loader):
+def load(stream, Loader=Loader, tz_aware_datetimes=False):
     """
     Parse the first YAML document in a stream
     and produce the corresponding Python object.
     """
-    loader = Loader(stream)
+    try:
+        loader = Loader(stream, tz_aware_datetimes=tz_aware_datetimes)
+    except TypeError:
+        loader = Loader(stream)
     try:
         return loader.get_single_data()
     finally:
         loader.dispose()
 
-def load_all(stream, Loader=Loader):
+def load_all(stream, Loader=Loader, tz_aware_datetimes=False):
     """
     Parse all YAML documents in a stream
     and produce corresponding Python objects.
     """
-    loader = Loader(stream)
+    try:
+        loader = Loader(stream, tz_aware_datetimes=tz_aware_datetimes)
+    except TypeError:
+        loader = Loader(stream)
     try:
         while loader.check_data():
             yield loader.get_data()
     finally:
         loader.dispose()
 
-def safe_load(stream):
+def safe_load(stream, tz_aware_datetimes=False):
     """
     Parse the first YAML document in a stream
     and produce the corresponding Python object.
     Resolve only basic YAML tags.
     """
-    return load(stream, SafeLoader)
+    return load(stream, SafeLoader, tz_aware_datetimes=tz_aware_datetimes)
 
-def safe_load_all(stream):
+def safe_load_all(stream, tz_aware_datetimes=False):
     """
     Parse all YAML documents in a stream
     and produce corresponding Python objects.
     Resolve only basic YAML tags.
     """
-    return load_all(stream, SafeLoader)
+    return load_all(stream, SafeLoader, tz_aware_datetimes=tz_aware_datetimes)
 
 def emit(events, stream=None, Dumper=Dumper,
         canonical=None, indent=None, width=None,

lib3/yaml/constructor.py

 
 import collections, datetime, base64, binascii, re, sys, types
 
+class FixedOffset(datetime.tzinfo):
+    def __init__(self, delta, name):
+        self.delta = delta
+        self.name = name
+
+    def utcoffset(self, dt):
+        return self.delta
+
+    def tzname(self, dt):
+        return self.name
+
+    def dst(self, dt):
+        return datetime.timedelta(0)
+
+    def __repr__(self):
+        return '<%s %s>' % (self.__class__.__name__, self.name)
+
+UTC = FixedOffset(datetime.timedelta(0), 'UTC')
+
 class ConstructorError(MarkedYAMLError):
     pass
 
 
 class SafeConstructor(BaseConstructor):
 
+    def __init__(self, tz_aware_datetimes=False):
+        BaseConstructor.__init__(self)
+        self.tz_aware_datetimes = tz_aware_datetimes
+
     def construct_scalar(self, node):
         if isinstance(node, MappingNode):
             for key_node, value_node in node.value:
         month = int(values['month'])
         day = int(values['day'])
         if not values['hour']:
-            return datetime.date(year, month, day)
+            if self.tz_aware_datetimes:
+                return datetime.datetime(year, month, day, 0, 0, 0, tzinfo=UTC)
+            else:
+                return datetime.date(year, month, day)
         hour = int(values['hour'])
         minute = int(values['minute'])
         second = int(values['second'])
             delta = datetime.timedelta(hours=tz_hour, minutes=tz_minute)
             if values['tz_sign'] == '-':
                 delta = -delta
-        data = datetime.datetime(year, month, day, hour, minute, second, fraction)
-        if delta:
-            data -= delta
-        return data
+            if self.tz_aware_datetimes:
+                tz_name = '%s%02d:%02d' % (values['tz_sign'],
+                                           tz_hour, tz_minute)
+                return datetime.datetime(year, month, day,
+                                         hour, minute, second, fraction,
+                                         tzinfo=FixedOffset(delta, tz_name))
+            else:
+                return (datetime.datetime(year, month, day,
+                                          hour, minute, second, fraction) -
+                        delta)
+        else:
+            if self.tz_aware_datetimes:
+                return datetime.datetime(year, month, day,
+                                         hour, minute, second, fraction,
+                                         tzinfo=UTC)
+            else:
+                return datetime.datetime(year, month, day,
+                                         hour, minute, second, fraction)
 
     def construct_yaml_omap(self, node):
         # Note: we do not check for duplicate keys, because it's too

lib3/yaml/cyaml.py

 
 class CBaseLoader(CParser, BaseConstructor, BaseResolver):
 
-    def __init__(self, stream):
+    def __init__(self, stream, tz_aware_datetimes=False):
         CParser.__init__(self, stream)
         BaseConstructor.__init__(self)
         BaseResolver.__init__(self)
 
 class CSafeLoader(CParser, SafeConstructor, Resolver):
 
-    def __init__(self, stream):
+    def __init__(self, stream, tz_aware_datetimes=False):
         CParser.__init__(self, stream)
-        SafeConstructor.__init__(self)
+        SafeConstructor.__init__(self, tz_aware_datetimes=tz_aware_datetimes)
         Resolver.__init__(self)
 
 class CLoader(CParser, Constructor, Resolver):
 
-    def __init__(self, stream):
+    def __init__(self, stream, tz_aware_datetimes=False):
         CParser.__init__(self, stream)
-        Constructor.__init__(self)
+        Constructor.__init__(self, tz_aware_datetimes=tz_aware_datetimes)
         Resolver.__init__(self)
 
 class CBaseDumper(CEmitter, BaseRepresenter, BaseResolver):

lib3/yaml/loader.py

 
 class BaseLoader(Reader, Scanner, Parser, Composer, BaseConstructor, BaseResolver):
 
-    def __init__(self, stream):
+    def __init__(self, stream, tz_aware_datetimes=False):
         Reader.__init__(self, stream)
         Scanner.__init__(self)
         Parser.__init__(self)
 
 class SafeLoader(Reader, Scanner, Parser, Composer, SafeConstructor, Resolver):
 
-    def __init__(self, stream):
+    def __init__(self, stream, tz_aware_datetimes=False):
         Reader.__init__(self, stream)
         Scanner.__init__(self)
         Parser.__init__(self)
         Composer.__init__(self)
-        SafeConstructor.__init__(self)
+        SafeConstructor.__init__(self, tz_aware_datetimes)
         Resolver.__init__(self)
 
 class Loader(Reader, Scanner, Parser, Composer, Constructor, Resolver):
 
-    def __init__(self, stream):
+    def __init__(self, stream, tz_aware_datetimes=False):
         Reader.__init__(self, stream)
         Scanner.__init__(self)
         Parser.__init__(self)
         Composer.__init__(self)
-        Constructor.__init__(self)
+        Constructor.__init__(self, tz_aware_datetimes)
         Resolver.__init__(self)
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.