Repository: falconry/falcon
Pull request #1517 (2019-05-06 15:49:16)

refactor(Response): Remove deprecated `stream_len` property
This appears to be the only existing functionality marked as deprecated hanging out in the code base. (Part of #1029.)

codecov[bot]: # [Codecov](https://codecov.io/gh/falconry/falcon/pull/1517?src=pr&el=h1) Report
> Merging [#1517](https://codecov.io/gh/falconry/falcon/pull/1517?src=pr&el=desc) into [master](https://codecov.io/gh/falconry/falcon/commit/ac0e33b91e73cc569ca6d991c8e55408829f2375?src=pr&el=desc) will **decrease** coverage by `0.07%`.
> The diff coverage is `60%`.

[![Impacted file tree graph](https://codecov.io/gh/falconry/falcon/pull/1517/graphs/tree.svg?width=650&token=zOtkfNQ3h6&height=150&src=pr)](https://codecov.io/gh/falconry/falcon/pull/1517?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master    #1517      +/-   ##
==========================================
- Coverage     100%   99.92%   -0.08%     
==========================================
  Files          38       38              
  Lines        2561     2565       +4     
  Branches      391      391              
==========================================
+ Hits         2561     2563       +2     
- Misses          0        2       +2
```


| [Impacted Files](https://codecov.io/gh/falconry/falcon/pull/1517?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [falcon/response.py](https://codecov.io/gh/falconry/falcon/pull/1517/diff?src=pr&el=tree#diff-ZmFsY29uL3Jlc3BvbnNlLnB5) | `98.9% <60%> (-1.1%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/falconry/falcon/pull/1517?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/falconry/falcon/pull/1517?src=pr&el=footer). Last update [ac0e33b...65f4928](https://codecov.io/gh/falconry/falcon/pull/1517?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

codecov[bot]: # [Codecov](https://codecov.io/gh/falconry/falcon/pull/1517?src=pr&el=h1) Report
> Merging [#1517](https://codecov.io/gh/falconry/falcon/pull/1517?src=pr&el=desc) into [master](https://codecov.io/gh/falconry/falcon/commit/ac0e33b91e73cc569ca6d991c8e55408829f2375?src=pr&el=desc) will **decrease** coverage by `0.07%`.
> The diff coverage is `60%`.

[![Impacted file tree graph](https://codecov.io/gh/falconry/falcon/pull/1517/graphs/tree.svg?width=650&token=zOtkfNQ3h6&height=150&src=pr)](https://codecov.io/gh/falconry/falcon/pull/1517?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master    #1517      +/-   ##
==========================================
- Coverage     100%   99.92%   -0.08%     
==========================================
  Files          38       38              
  Lines        2561     2565       +4     
  Branches      391      391              
==========================================
+ Hits         2561     2563       +2     
- Misses          0        2       +2
```


| [Impacted Files](https://codecov.io/gh/falconry/falcon/pull/1517?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [falcon/response.py](https://codecov.io/gh/falconry/falcon/pull/1517/diff?src=pr&el=tree#diff-ZmFsY29uL3Jlc3BvbnNlLnB5) | `98.9% <60%> (-1.1%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/falconry/falcon/pull/1517?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/falconry/falcon/pull/1517?src=pr&el=footer). Last update [ac0e33b...65f4928](https://codecov.io/gh/falconry/falcon/pull/1517?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

karlhigley: See also #1463; the property was deprecated as of 2.0.
karlhigley: Should the [`stream_len` parameter of `BoundedStream`](https://github.com/falconry/falcon/blob/master/falcon/request_helpers.py#L190) also change? Seems like it should work as written, but could be renamed for consistency.
karlhigley: (As far as I can tell, Hug only [interacts](https://github.com/hugapi/hug/blob/84e4f5138ed1b91622500731ba738c8331872308/hug/interface.py#L743) with this property through `set_stream`.)
vytas7: IMHO `BoundedStream` could stay as-is.
kgriffs: Since this patch contains edits to the changelogs, it is going to conflict with the towncrier PR. I am going to wait to merge this until we've decided what we want to do about that conflict.

Patch:
diff --git a/CHANGES.rst b/CHANGES.rst
index 28a95a9..bd434af 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -20,6 +20,9 @@ Breaking Changes
 
 - Header-related methods of the ``falcon.Response`` class no longer coerce
   the passed header name to a string via ``str()``.
+- The deprecated ``stream_len`` property was removed from the ``Response``
+  class. Please use ``Response.set_stream()`` or ``Response.content_length``
+  instead.
 
 New & Improved
 --------------
@@ -96,9 +99,6 @@ Breaking Changes
   ``True``.
 - ``independent_middleware`` kwarg on ``falcon.API`` now defaults to ``True``
   instead of ``False``.
-- The deprecated ``stream_len`` property was removed from the ``Response``
-  class. Please use ``Response.set_stream()`` or ``Response.content_length``
-  instead.
 - ``Request.context_type`` was changed from dict to a bare class implementing
   the mapping interface.
 - ``Response.context_type`` was changed from dict to a bare class implementing
diff --git a/docs/changes/3.0.0.rst b/docs/changes/3.0.0.rst
index f4b370e..bcfd688 100644
--- a/docs/changes/3.0.0.rst
+++ b/docs/changes/3.0.0.rst
@@ -20,6 +20,9 @@ Breaking Changes
 
 - Header-related methods of the :class:`~.Response` class no longer coerce
   the passed header name to a string via ``str()``.
+- The deprecated ``stream_len`` property was removed from the ``Response``
+  class. Please use ``Response.set_stream()`` or ``Response.content_length``
+  instead.
 
 New & Improved
 --------------
diff --git a/falcon/response.py b/falcon/response.py
index cd78b43..177f7a7 100644
--- a/falcon/response.py
+++ b/falcon/response.py
@@ -35,11 +35,10 @@ from falcon.util.uri import encode_value as uri_encode_value
 
 GMT_TIMEZONE = TimezoneGMT()
 
-# TODO(kgriffs): Uncomment when 3.0 development opens
-# _STREAM_LEN_REMOVED_MSG = (
-#     'The deprecated stream_len property was removed in Falcon 3.0. '
-#     'Please use Response.set_stream() or Response.content_length instead.'
-# )
+_STREAM_LEN_REMOVED_MSG = (
+    'The deprecated stream_len property was removed in Falcon 3.0. '
+    'Please use Response.set_stream() or Response.content_length instead.'
+)
 
 
 class Response:
@@ -100,8 +99,6 @@ class Response:
                 resource cleanup, it can implement a close() method to do so.
                 The close() method will be called upon completion of the request.
 
-        stream_len (int): Deprecated alias for :attr:`content_length`.
-
         context (dict): Dictionary to hold any data about the response which is
             specific to your app. Falcon itself will not interact with this
             attribute after it has been initialized.
@@ -239,19 +236,17 @@ class Response:
         # just be thrown away.
         self._data = None
 
-    # TODO(kgriffs): Uncomment when 3.0 development opens
-    # @property
-    # def stream_len(self):
-    #     # NOTE(kgriffs): Provide some additional information by raising the
-    #     #   error explicitly.
-    #     raise AttributeError(_STREAM_LEN_REMOVED_MSG)
+    @property
+    def stream_len(self):
+        # NOTE(kgriffs): Provide some additional information by raising the
+        #   error explicitly.
+        raise AttributeError(_STREAM_LEN_REMOVED_MSG)
 
-    # TODO(kgriffs): Uncomment when 3.0 development opens
-    # @stream_len.setter
-    # def stream_len(self, value):
-    #     # NOTE(kgriffs): We explicitly disallow setting the deprecated attribute
-    #     #   so that apps relying on it do not fail silently.
-    #     raise AttributeError(_STREAM_LEN_REMOVED_MSG)
+    @stream_len.setter
+    def stream_len(self, value):
+        # NOTE(kgriffs): We explicitly disallow setting the deprecated attribute
+        #   so that apps relying on it do not fail silently.
+        raise AttributeError(_STREAM_LEN_REMOVED_MSG)
 
     def __repr__(self):
         return '<%s: %s>' % (self.__class__.__name__, self.status)
@@ -799,9 +794,6 @@ class Response:
         """,
     )
 
-    # TODO(kgriffs): Remove deprecated alias once development opens for 3.0
-    stream_len = content_length
-
     content_range = header_property(
         'Content-Range',
         """A tuple to use in constructing a value for the Content-Range header.


Test patch:
diff --git a/tests/test_headers.py b/tests/test_headers.py
index 8040048..1ee19c8 100644
--- a/tests/test_headers.py
+++ b/tests/test_headers.py
@@ -212,8 +212,7 @@ class ContentLengthHeaderResource:
         self._data = data
 
     def on_get(self, req, resp):
-        # NOTE(kgriffs): Use stream_len for now to cover the deprecated alias
-        resp.stream_len = self._content_length
+        resp.content_length = self._content_length
 
         if self._body:
             resp.body = self._body
diff --git a/tests/test_response.py b/tests/test_response.py
index 8c61664..80b59b5 100644
--- a/tests/test_response.py
+++ b/tests/test_response.py
@@ -51,12 +51,11 @@ def test_response_attempt_to_set_read_only_headers():
     assert headers['x-things3'] == 'thing-3a, thing-3b'
 
 
-# TODO(kgriffs): Uncomment when 3.0 development opens
-# def test_response_removed_stream_len():
-#     resp = falcon.Response()
+def test_response_removed_stream_len():
+    resp = falcon.Response()
 
-#     with pytest.raises(AttributeError):
-#         resp.stream_len = 128
+    with pytest.raises(AttributeError):
+        resp.stream_len = 128
 
-#     with pytest.raises(AttributeError):
-#         resp.stream_len
+    with pytest.raises(AttributeError):
+        resp.stream_len