Hello community,

here is the log from the commit of package python-hyperframe for 
openSUSE:Factory checked in at 2017-04-26 21:43:52
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-hyperframe (Old)
 and      /work/SRC/openSUSE:Factory/.python-hyperframe.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-hyperframe"

Wed Apr 26 21:43:52 2017 rev:2 rq:490324 version:5.0.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-hyperframe/python-hyperframe.changes      
2017-04-14 13:32:55.688033303 +0200
+++ /work/SRC/openSUSE:Factory/.python-hyperframe.new/python-hyperframe.changes 
2017-04-26 21:43:52.942322795 +0200
@@ -1,0 +2,11 @@
+Sat Apr 22 12:10:15 UTC 2017 - [email protected]
+
+- Update to version 5.0.0
+  Backwards Incompatible API Changes:
+  * Added support for unknown extension frames. These will be
+    returned in the new ExtensionFrame object. The flag information
+    for these frames is persisted in flag_byte if needed.
+- Enabled tests
+- Fixed source URL
+
+-------------------------------------------------------------------

Old:
----
  hyperframe-4.0.2.tar.gz

New:
----
  hyperframe-5.0.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-hyperframe.spec ++++++
--- /var/tmp/diff_new_pack.kXXZm7/_old  2017-04-26 21:43:53.690217214 +0200
+++ /var/tmp/diff_new_pack.kXXZm7/_new  2017-04-26 21:43:53.694216649 +0200
@@ -18,18 +18,20 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-hyperframe
-Version:        4.0.2
+Version:        5.0.0
 Release:        0
 Summary:        HTTP/2 framing layer for Python
 License:        MIT
 Group:          Development/Languages/Python
 Url:            http://hyper.rtfd.org
-Source0:        
https://pypi.io/packages/source/h/hyperframe/hyperframe-%{version}.tar.gz
+Source0:        
https://files.pythonhosted.org/packages/source/h/hyperframe/hyperframe-%{version}.tar.gz
 BuildRequires:  %{python_module devel}
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros
-BuildArch:      noarch
+# test requirements
+BuildRequires:  %{python_module pytest}
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
+BuildArch:      noarch
 %python_subpackages
 
 %description
@@ -47,10 +49,13 @@
 %python_install
 %python_expand %fdupes -s %{buildroot}%{$python_sitelib}
 
+%check
+%python_expand PYTHONPATH=%{buildroot}%{$python_sitelib} 
py.test-%{$python_version} -v
+
 %files %{python_files}
 %defattr(-,root,root,-)
 %doc LICENSE README.rst CONTRIBUTORS.rst HISTORY.rst
 %{python_sitelib}/hyperframe
-%{python_sitelib}/hyperframe-%{version}-py%{py_ver}.egg-info
+%{python_sitelib}/hyperframe-%{version}-py%{python_version}.egg-info
 
 %changelog

++++++ hyperframe-4.0.2.tar.gz -> hyperframe-5.0.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyperframe-4.0.2/HISTORY.rst 
new/hyperframe-5.0.0/HISTORY.rst
--- old/hyperframe-4.0.2/HISTORY.rst    2017-02-20 18:26:13.000000000 +0100
+++ new/hyperframe-5.0.0/HISTORY.rst    2017-03-07 12:40:30.000000000 +0100
@@ -1,6 +1,15 @@
 Release History
 ===============
 
+5.0.0 (2017-03-07)
+------------------
+
+**Backwards Incompatible API Changes**
+
+- Added support for unknown extension frames. These will be returned in the new
+  ``ExtensionFrame`` object. The flag information for these frames is persisted
+  in ``flag_byte`` if needed.
+
 4.0.2 (2017-02-20)
 ------------------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyperframe-4.0.2/PKG-INFO 
new/hyperframe-5.0.0/PKG-INFO
--- old/hyperframe-4.0.2/PKG-INFO       2017-02-20 18:30:50.000000000 +0100
+++ new/hyperframe-5.0.0/PKG-INFO       2017-03-07 12:43:28.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: hyperframe
-Version: 4.0.2
+Version: 5.0.0
 Summary: HTTP/2 framing layer for Python
 Home-page: http://hyper.rtfd.org
 Author: Cory Benfield
@@ -50,6 +50,15 @@
         Release History
         ===============
         
+        5.0.0 (2017-03-07)
+        ------------------
+        
+        **Backwards Incompatible API Changes**
+        
+        - Added support for unknown extension frames. These will be returned 
in the new
+          ``ExtensionFrame`` object. The flag information for these frames is 
persisted
+          in ``flag_byte`` if needed.
+        
         4.0.2 (2017-02-20)
         ------------------
         
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyperframe-4.0.2/hyperframe/__init__.py 
new/hyperframe-5.0.0/hyperframe/__init__.py
--- old/hyperframe-4.0.2/hyperframe/__init__.py 2017-02-20 18:26:21.000000000 
+0100
+++ new/hyperframe-5.0.0/hyperframe/__init__.py 2017-03-07 12:40:30.000000000 
+0100
@@ -5,4 +5,4 @@
 
 A module for providing a pure-Python HTTP/2 framing layer.
 """
-__version__ = '4.0.2'
+__version__ = '5.0.0'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyperframe-4.0.2/hyperframe/frame.py 
new/hyperframe-5.0.0/hyperframe/frame.py
--- old/hyperframe-4.0.2/hyperframe/frame.py    2017-02-20 18:12:07.000000000 
+0100
+++ new/hyperframe-5.0.0/hyperframe/frame.py    2017-03-07 11:42:21.000000000 
+0100
@@ -88,15 +88,21 @@
         )
 
     @staticmethod
-    def parse_frame_header(header):
+    def parse_frame_header(header, strict=False):
         """
         Takes a 9-byte frame header and returns a tuple of the appropriate
         Frame object and the length that needs to be read from the socket.
 
         This populates the flags field, and determines how long the body is.
 
+        :param strict: Whether to raise an exception when encountering a frame
+            not defined by spec and implemented by hyperframe.
+
         :raises hyperframe.exceptions.UnknownFrameError: If a frame of unknown
             type is received.
+
+        .. versionchanged:: 5.0.0
+            Added :param:`strict` to accommodate :class:`ExtensionFrame`
         """
         try:
             fields = _STRUCT_HBBBL.unpack(header)
@@ -109,10 +115,13 @@
         flags = fields[3]
         stream_id = fields[4] & 0x7FFFFFFF
 
-        if type not in FRAMES:
-            raise UnknownFrameError(type, length)
+        try:
+            frame = FRAMES[type](stream_id)
+        except KeyError:
+            if strict:
+                raise UnknownFrameError(type, length)
+            frame = ExtensionFrame(type=type, stream_id=stream_id)
 
-        frame = FRAMES[type](stream_id)
         frame.parse_flags(flags)
         return (frame, length)
 
@@ -736,6 +745,61 @@
         self.body_len = len(data)
 
 
+class ExtensionFrame(Frame):
+    """
+    ExtensionFrame is used to wrap frames which are not natively interpretable
+    by hyperframe.
+
+    Although certain byte prefixes are ordained by specification to have
+    certain contextual meanings, frames with other prefixes are not prohibited,
+    and may be used to communicate arbitrary meaning between HTTP/2 peers.
+
+    Thus, hyperframe, rather than raising an exception when such a frame is
+    encountered, wraps it in a generic frame to be properly acted upon by
+    upstream consumers which might have additional context on how to use it.
+
+    .. versionadded:: 5.0.0
+    """
+
+    stream_association = _STREAM_ASSOC_EITHER
+
+    def __init__(self, type, stream_id, **kwargs):
+        super(ExtensionFrame, self).__init__(stream_id, **kwargs)
+        self.type = type
+        self.flag_byte = None
+
+    def parse_flags(self, flag_byte):
+        """
+        For extension frames, we parse the flags by just storing a flag byte.
+        """
+        self.flag_byte = flag_byte
+
+    def parse_body(self, data):
+        self.body = data.tobytes()
+        self.body_len = len(data)
+
+    def serialize(self):
+        """
+        A broad override of the serialize method that ensures that the data
+        comes back out exactly as it came in. This should not be used in most
+        user code: it exists only as a helper method if frames need to be
+        reconstituted.
+        """
+        # Build the frame header.
+        # First, get the flags.
+        flags = self.flag_byte
+
+        header = _STRUCT_HBBBL.pack(
+            (self.body_len >> 8) & 0xFFFF,  # Length spread over top 24 bits
+            self.body_len & 0xFF,
+            self.type,
+            flags,
+            self.stream_id & 0x7FFFFFFF  # Stream ID is 32 bits.
+        )
+
+        return header + self.body
+
+
 _FRAME_CLASSES = [
     DataFrame,
     HeadersFrame,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyperframe-4.0.2/hyperframe.egg-info/PKG-INFO 
new/hyperframe-5.0.0/hyperframe.egg-info/PKG-INFO
--- old/hyperframe-4.0.2/hyperframe.egg-info/PKG-INFO   2017-02-20 
18:30:50.000000000 +0100
+++ new/hyperframe-5.0.0/hyperframe.egg-info/PKG-INFO   2017-03-07 
12:43:28.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: hyperframe
-Version: 4.0.2
+Version: 5.0.0
 Summary: HTTP/2 framing layer for Python
 Home-page: http://hyper.rtfd.org
 Author: Cory Benfield
@@ -50,6 +50,15 @@
         Release History
         ===============
         
+        5.0.0 (2017-03-07)
+        ------------------
+        
+        **Backwards Incompatible API Changes**
+        
+        - Added support for unknown extension frames. These will be returned 
in the new
+          ``ExtensionFrame`` object. The flag information for these frames is 
persisted
+          in ``flag_byte`` if needed.
+        
         4.0.2 (2017-02-20)
         ------------------
         
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyperframe-4.0.2/test/test_frames.py 
new/hyperframe-5.0.0/test/test_frames.py
--- old/hyperframe-4.0.2/test/test_frames.py    2017-02-20 18:12:07.000000000 
+0100
+++ new/hyperframe-5.0.0/test/test_frames.py    2017-03-07 11:42:21.000000000 
+0100
@@ -2,7 +2,7 @@
 from hyperframe.frame import (
     Frame, Flags, DataFrame, PriorityFrame, RstStreamFrame, SettingsFrame,
     PushPromiseFrame, PingFrame, GoAwayFrame, WindowUpdateFrame, HeadersFrame,
-    ContinuationFrame, AltSvcFrame
+    ContinuationFrame, AltSvcFrame, ExtensionFrame
 )
 from hyperframe.exceptions import (
     UnknownFrameError, InvalidPaddingError, InvalidFrameError
@@ -35,10 +35,12 @@
         with pytest.raises(NotImplementedError):
             f.parse_body(data)
 
-    def test_parse_frame_header_unknown_type(self):
+    def test_parse_frame_header_unknown_type_strict(self):
         with pytest.raises(UnknownFrameError) as excinfo:
-            Frame.parse_frame_header(b'\x00\x00\x59\xFF\x00\x00\x00\x00\x01')
-
+            Frame.parse_frame_header(
+                b'\x00\x00\x59\xFF\x00\x00\x00\x00\x01',
+                strict=True
+            )
         exception = excinfo.value
         assert exception.frame_type == 0xFF
         assert exception.length == 0x59
@@ -53,6 +55,36 @@
 
         assert f.stream_id == 0
 
+    def test_parse_frame_header_unknown_type(self):
+        f, l = Frame.parse_frame_header(
+            b'\x00\x00\x59\xFF\x00\x00\x00\x00\x01'
+        )
+        assert f.type == 0xFF
+        assert l == 0x59
+        assert isinstance(f, ExtensionFrame)
+        assert f.stream_id == 1
+
+    def test_flags_are_persisted(self):
+        f, l = Frame.parse_frame_header(
+            b'\x00\x00\x59\xFF\x09\x00\x00\x00\x01'
+        )
+        assert f.type == 0xFF
+        assert l == 0x59
+        assert f.flag_byte == 0x09
+
+    def test_parse_body_unknown_type(self):
+        f = decode_frame(
+            b'\x00\x00\x0C\xFF\x00\x00\x00\x00\x01hello world!'
+        )
+        assert f.body == b'hello world!'
+        assert f.body_len == 12
+        assert f.stream_id == 1
+
+    def test_can_round_trip_unknown_frames(self):
+        frame_data = b'\x00\x00\x0C\xFF\x00\x00\x00\x00\x01hello world!'
+        f = decode_frame(frame_data)
+        assert f.serialize() == frame_data
+
     def test_repr(self, monkeypatch):
         f = Frame(stream_id=0)
         monkeypatch.setattr(Frame, "serialize_body", lambda _: b"body")


Reply via email to