Repository: postlund/pyatv
Pull request #1044 (2021-04-27 21:24:52)

build(deps): bump pylint from 2.7.4 to 2.8.2
Bumps [pylint](https://github.com/PyCQA/pylint) from 2.7.4 to 2.8.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/PyCQA/pylint/releases">pylint's releases</a>.</em></p>
<blockquote>
<h2>pylint-2.8.1</h2>
<ul>
<li>
<p>Add numversion back (temporarily) in <code>__pkginfo__</code> because it broke Pylama and revert the unnecessary
<code>pylint.version</code> breaking change.</p>
<p>Closes <a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/4399">#4399</a></p>
</li>
</ul>
<h2>pylint-2.8.0</h2>
<ul>
<li>
<p>New refactoring message <code>consider-using-with</code>. This message is emitted if resource-allocating functions or methods of the
standard library (like <code>open()</code> or <code>threading.Lock.acquire()</code>) that can be used as a context manager are called without
a <code>with</code> block.</p>
<p>Closes <a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/3413">#3413</a></p>
</li>
<li>
<p>Resolve false positives on unused variables in decorator functions</p>
<p>Closes <a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/4252">#4252</a></p>
</li>
<li>
<p>Add new extension <code>ConfusingConsecutiveElifChecker</code>. This optional checker emits a refactoring message (R5601 <code>confusing-consecutive-elif</code>)
if if/elif statements with different indentation levels follow directly one after the other.</p>
</li>
<li>
<p>New option <code>--output=&lt;file&gt;</code> to output result to a file rather than printing to stdout.</p>
<p>Closes <a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/1070">#1070</a></p>
</li>
<li>
<p>Use a prescriptive message for <code>unidiomatic-typecheck</code></p>
<p>Closes <a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/3891">#3891</a></p>
</li>
<li>
<p>Apply <code>const-naming-style</code> to module constants annotated with
<code>typing.Final</code></p>
</li>
<li>
<p>The packaging is now done via setuptools exclusively. <code>doc</code>, <code>tests</code>, <code>man</code>, <code>elisp</code> and <code>Changelog</code> are
not packaged anymore - reducing the size of the package by 75%.</p>
</li>
<li>
<p>Debian packaging is now  (officially) done in <a href="https://salsa.debian.org/python-team/packages/pylint">https://salsa.debian.org/python-team/packages/pylint</a>.</p>
</li>
<li>
<p>The 'doc' extra-require has been removed.</p>
</li>
<li>
<p><code>__pkginfo__</code> now only contain <code>__version__</code> (also accessible with <code>pylint.__version__</code>), other meta-information are still
accessible with <code>import importlib;metadata.metadata('pylint')</code>.</p>
</li>
<li>
<p>COPYING has been renamed to LICENSE for standardization.</p>
</li>
<li>
<p>Fix false-positive <code>used-before-assignment</code> in function returns.</p>
<p>Closes <a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/4301">#4301</a></p>
</li>
<li>
<p>Updated <code>astroid</code> to 2.5.3</p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/PyCQA/pylint/blob/master/ChangeLog">pylint's changelog</a>.</em></p>
<blockquote>
<h1>What's New in Pylint 2.8.2?</h1>
<p>Release date: 2021-04-26</p>
<p>..
Put new features and bugfixes here and also in 'doc/whatsnew/2.9.rst'</p>
<ul>
<li>
<p>Keep <code>__pkginfo__.numversion</code> a tuple to avoid breaking pylint-django.</p>
<p>Closes <a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/4405">#4405</a></p>
</li>
<li>
<p>scm_setuptools has been added to the packaging.</p>
</li>
<li>
<p>Pylint's tags are now the standard form <code>vX.Y.Z</code> and not <code>pylint-X.Y.Z</code> anymore.</p>
</li>
</ul>
<h1>What's New in Pylint 2.8.1?</h1>
<p>Release date: 2021-04-25</p>
<p>..
Put new features and bugfixes here and also in 'doc/whatsnew/2.9.rst'</p>
<ul>
<li>
<p>Add numversion back (temporarily) in <code>__pkginfo__</code> because it broke Pylama and revert the unnecessary
<code>pylint.version</code> breaking change.</p>
<p>Closes <a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/4399">#4399</a></p>
</li>
</ul>
<h1>What's New in Pylint 2.8.0?</h1>
<p>Release date: 2021-04-24</p>
<ul>
<li>
<p>New refactoring message <code>consider-using-with</code>. This message is emitted if resource-allocating functions or methods of the
standard library (like <code>open()</code> or <code>threading.Lock.acquire()</code>) that can be used as a context manager are called without
a <code>with</code> block.</p>
<p>Closes <a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/3413">#3413</a></p>
</li>
<li>
<p>Resolve false positives on unused variables in decorator functions</p>
<p>Closes <a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/4252">#4252</a></p>
</li>
<li>
<p>Add new extension <code>ConfusingConsecutiveElifChecker</code>. This optional checker emits a refactoring message (R5601 <code>confusing-consecutive-elif</code>)
if if/elif statements with different indentation levels follow directly one after the other.</p>
</li>
<li>
<p>New option <code>--output=&lt;file&gt;</code> to output result to a file rather than printing to stdout.</p>
<p>Closes <a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/1070">#1070</a></p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/PyCQA/pylint/commit/091cb92314dc701f10390136da78fbbb362e892e"><code>091cb92</code></a> Update copyrite notice</li>
<li><a href="https://github.com/PyCQA/pylint/commit/f9245c5ccbbe6817604113b0b53b2630ed4069ae"><code>f9245c5</code></a> Release with standard version tag</li>
<li><a href="https://github.com/PyCQA/pylint/commit/c234b3efe19db81d0d03d46c4afa6886129bd25c"><code>c234b3e</code></a> Update documentation and changelog</li>
<li><a href="https://github.com/PyCQA/pylint/commit/76a232e0cd3abb0f2d395cd2fe035046daef80fb"><code>76a232e</code></a> Add scm_setuptools for packaging</li>
<li><a href="https://github.com/PyCQA/pylint/commit/a4fac223dfeb36952088ed361e27ee57c2ae45b8"><code>a4fac22</code></a> Changes after black update</li>
<li><a href="https://github.com/PyCQA/pylint/commit/316af5f4936686337e12ba3ca8a7d077a855bdfb"><code>316af5f</code></a> Update black to 21.4b0</li>
<li><a href="https://github.com/PyCQA/pylint/commit/9e2394d211cf81ca1864de58c36461bf885500bb"><code>9e2394d</code></a> Add changelog entry</li>
<li><a href="https://github.com/PyCQA/pylint/commit/ea8a6eb6b956d139bb142eb45788a8314789b0c9"><code>ea8a6eb</code></a> Keep <strong>pkginfo</strong>.numversion a tuple</li>
<li><a href="https://github.com/PyCQA/pylint/commit/530909cd0baf9cb17c6bd2ae36687df96107c091"><code>530909c</code></a> Bump black from 20.8b1 to 21.4b0</li>
<li><a href="https://github.com/PyCQA/pylint/commit/a74259190d2d3266130baf5eac201e944a48e14e"><code>a742591</code></a> Fix image link in readme</li>
<li>Additional commits viewable in <a href="https://github.com/PyCQA/pylint/compare/pylint-2.7.4...v2.8.2">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://api.dependabot.com/badges/compatibility_score?dependency-name=pylint&package-manager=pip&previous-version=2.7.4&new-version=2.8.2)](https://dependabot.com/compatibility-score/?dependency-name=pylint&package-manager=pip&previous-version=2.7.4&new-version=2.8.2)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
If all status checks pass Dependabot will automatically merge this pull request.

[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
- `@dependabot badge me` will comment on this PR with code to add a "Dependabot enabled" badge to your readme

Additionally, you can set the following in the `.dependabot/config.yml` file in this repo:
- Update frequency
- Automerge options (never/patch/minor, and dev/runtime dependencies)
- Out-of-range updates (receive only lockfile updates, if desired)
- Security updates (receive only security updates, if desired)



</details>

<a href="https://gitpod.io/#https://github.com/postlund/pyatv/pull/1044"><img src="https://gitpod.io/button/open-in-gitpod.svg"/></a>



codecov[bot]: # [Codecov](https://codecov.io/gh/postlund/pyatv/pull/1044?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl) Report
> Merging [#1044](https://codecov.io/gh/postlund/pyatv/pull/1044?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl) (c096a94) into [master](https://codecov.io/gh/postlund/pyatv/commit/021cc7a1f90538bf92889dca455ed0250dfd3a49?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl) (021cc7a) will **increase** coverage by `1.61%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/postlund/pyatv/pull/1044/graphs/tree.svg?width=650&height=150&src=pr&token=wb6azJjRSY&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl)](https://codecov.io/gh/postlund/pyatv/pull/1044?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl)

```diff
@@            Coverage Diff             @@
##           master    #1044      +/-   ##
==========================================
+ Coverage   93.98%   95.59%   +1.61%     
==========================================
  Files          47       47              
  Lines        4471     4450      -21     
==========================================
+ Hits         4202     4254      +52     
+ Misses        269      196      -73     
```


| [Impacted Files](https://codecov.io/gh/postlund/pyatv/pull/1044?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl) | Coverage Δ | |
|---|---|---|
| [pyatv/dmap/\_\_init\_\_.py](https://codecov.io/gh/postlund/pyatv/pull/1044/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl#diff-cHlhdHYvZG1hcC9fX2luaXRfXy5weQ==) | `96.79% <100.00%> (-0.04%)` | :arrow_down: |
| [pyatv/interface.py](https://codecov.io/gh/postlund/pyatv/pull/1044/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl#diff-cHlhdHYvaW50ZXJmYWNlLnB5) | `99.07% <100.00%> (-0.01%)` | :arrow_down: |
| [pyatv/mrp/\_\_init\_\_.py](https://codecov.io/gh/postlund/pyatv/pull/1044/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl#diff-cHlhdHYvbXJwL19faW5pdF9fLnB5) | `95.02% <100.00%> (+0.24%)` | :arrow_up: |
| [pyatv/airplay/server.py](https://codecov.io/gh/postlund/pyatv/pull/1044/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl#diff-cHlhdHYvYWlycGxheS9zZXJ2ZXIucHk=) | `90.32% <0.00%> (-0.59%)` | :arrow_down: |
| [pyatv/mrp/connection.py](https://codecov.io/gh/postlund/pyatv/pull/1044/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl#diff-cHlhdHYvbXJwL2Nvbm5lY3Rpb24ucHk=) | `81.05% <0.00%> (-0.20%)` | :arrow_down: |
| [pyatv/mrp/pairing.py](https://codecov.io/gh/postlund/pyatv/pull/1044/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl#diff-cHlhdHYvbXJwL3BhaXJpbmcucHk=) | `97.56% <0.00%> (-0.12%)` | :arrow_down: |
| [pyatv/companion/connection.py](https://codecov.io/gh/postlund/pyatv/pull/1044/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl#diff-cHlhdHYvY29tcGFuaW9uL2Nvbm5lY3Rpb24ucHk=) | `90.29% <0.00%> (-0.10%)` | :arrow_down: |
| [pyatv/dmap/pairing.py](https://codecov.io/gh/postlund/pyatv/pull/1044/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl#diff-cHlhdHYvZG1hcC9wYWlyaW5nLnB5) | `96.55% <0.00%> (-0.08%)` | :arrow_down: |
| ... and [13 more](https://codecov.io/gh/postlund/pyatv/pull/1044/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/postlund/pyatv/pull/1044?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/postlund/pyatv/pull/1044?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl). Last update [7979b1b...c096a94](https://codecov.io/gh/postlund/pyatv/pull/1044?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl).

dependabot-preview[bot]: One of your CI runs failed on this pull request, so Dependabot won't merge it.

- [3.9 / windows-latest](https://github.com/postlund/pyatv/runs/2452173480)
- [3.8 / windows-latest](https://github.com/postlund/pyatv/runs/2452173461)
- [3.7 / windows-latest](https://github.com/postlund/pyatv/runs/2452173440)
- [3.6 / windows-latest](https://github.com/postlund/pyatv/runs/2452173412)
- [3.9 / macos-latest](https://github.com/postlund/pyatv/runs/2452173382)
- [3.8 / macos-latest](https://github.com/postlund/pyatv/runs/2452173358)
- [3.9 / ubuntu-latest](https://github.com/postlund/pyatv/runs/2452173291)
- [3.8 / ubuntu-latest](https://github.com/postlund/pyatv/runs/2452173274)

Dependabot will still automatically merge this pull request if you amend it and your tests pass.
gitpod-io[bot]: 

<a href="https://gitpod.io/#https://github.com/postlund/pyatv/pull/1044"><img src="https://gitpod.io/button/open-in-gitpod.svg"/></a>



Patch:
diff --git a/pyatv/airplay/__init__.py b/pyatv/airplay/__init__.py
index 29187eb9..b39ef811 100644
--- a/pyatv/airplay/__init__.py
+++ b/pyatv/airplay/__init__.py
@@ -42,10 +42,9 @@ class AirPlayFeatures(Features):
 class AirPlayStream(Stream):  # pylint: disable=too-few-public-methods
     """Implementation of stream API with AirPlay."""
 
-    def __init__(self, config, loop: asyncio.AbstractEventLoop) -> None:
+    def __init__(self, config) -> None:
         """Initialize a new AirPlayStreamAPI instance."""
         self.config = config
-        self.loop = loop
         self.service = self.config.get_service(Protocol.AirPlay)
         self.identifier = None
         self.credentials = self._get_credentials()
@@ -77,7 +76,7 @@ class AirPlayStream(Stream):  # pylint: disable=too-few-public-methods
         http = net.HttpSession(
             session, f"http://{self.config.address}:{self.service.port}/"
         )
-        player = AirPlayPlayer(self.loop, http)
+        player = AirPlayPlayer(http)
 
         # If credentials have been loaded, do device verification first
         if self.credentials:
@@ -135,7 +134,7 @@ def setup(
     assert service is not None
 
     # TODO: Split up in connect/protocol and Stream implementation
-    stream = AirPlayStream(config, loop)
+    stream = AirPlayStream(config)
 
     interfaces[Features].register(
         AirPlayFeatures(cast(conf.AirPlayService, service)), Protocol.AirPlay
diff --git a/pyatv/airplay/player.py b/pyatv/airplay/player.py
index c733589b..f390ec62 100644
--- a/pyatv/airplay/player.py
+++ b/pyatv/airplay/player.py
@@ -21,9 +21,8 @@ HEADERS = {
 class AirPlayPlayer:
     """This class helps with playing media from an URL."""
 
-    def __init__(self, loop, http):
+    def __init__(self, http):
         """Initialize a new AirPlay instance."""
-        self.loop = loop
         self.http = http
 
     async def play_url(self, url, position=0):
@@ -52,7 +51,7 @@ class AirPlayPlayer:
                 _LOGGER.debug(
                     "Failed to stream %s, retry %d of %d", url, retry, PLAY_RETRIES
                 )
-                await asyncio.sleep(1.0, loop=self.loop)
+                await asyncio.sleep(1.0)
                 continue
 
             # TODO: Should be more fine-grained
@@ -93,4 +92,4 @@ class AirPlayPlayer:
                 _LOGGER.debug("media playback ended")
                 break
 
-            await asyncio.sleep(1, loop=self.loop)
+            await asyncio.sleep(1)
diff --git a/pyatv/dmap/__init__.py b/pyatv/dmap/__init__.py
index cf8f093c..95610b7b 100644
--- a/pyatv/dmap/__init__.py
+++ b/pyatv/dmap/__init__.py
@@ -519,7 +519,7 @@ class DmapPushUpdater(PushUpdater):
             # Sleep some time before waiting for updates
             if not first_call and self._initial_delay > 0:
                 _LOGGER.debug("Initial delay set to %d", self._initial_delay)
-                await asyncio.sleep(self._initial_delay, loop=self.loop)
+                await asyncio.sleep(self._initial_delay)
                 first_call = False
 
             try:
diff --git a/pyatv/support/chacha20.py b/pyatv/support/chacha20.py
index 527f171b..378e22cf 100644
--- a/pyatv/support/chacha20.py
+++ b/pyatv/support/chacha20.py
@@ -1,8 +1,6 @@
 """Transparent encryption layer using Chacha20_Pooly1305."""
 from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305
 
-from pyatv import exceptions
-
 NONCE_LENGTH = 12
 
 
@@ -43,7 +41,4 @@ class Chacha20Cipher:
 
         decrypted = self._enc_in.decrypt(nounce, data, aad)
 
-        if not decrypted:
-            raise exceptions.AuthenticationError("data decrypt failed")
-
         return bytes(decrypted)


Test patch:
diff --git a/requirements_test.txt b/requirements_test.txt
index 15fedebb..43307eb7 100644
--- a/requirements_test.txt
+++ b/requirements_test.txt
@@ -3,7 +3,7 @@ codecov==2.1.11
 deepdiff==5.5.0
 flake8==3.9.2
 isort==5.8.0
-pylint==2.7.4
+pylint==2.8.2
 pytest==6.2.4
 pytest-asyncio==0.15.1
 pytest-cov==2.12.0
diff --git a/tests/airplay/test_airplay.py b/tests/airplay/test_airplay.py
index 0d76b416..24eb1a11 100644
--- a/tests/airplay/test_airplay.py
+++ b/tests/airplay/test_airplay.py
@@ -28,7 +28,7 @@ class AirPlayPlayerTest(AioHTTPTestCase):
         http = net.HttpSession(
             self.session, "http://127.0.0.1:{0}/".format(self.server.port)
         )
-        self.player = player.AirPlayPlayer(self.loop, http)
+        self.player = player.AirPlayPlayer(http)
 
     async def tearDownAsync(self):
         unstub_sleep()
diff --git a/tests/companion/test_companion_auth.py b/tests/companion/test_companion_auth.py
index 5a9c4404..9b15571f 100644
--- a/tests/companion/test_companion_auth.py
+++ b/tests/companion/test_companion_auth.py
@@ -68,6 +68,14 @@ class CompanionAuthFunctionalTest(AioHTTPTestCase):
         self.assertTrue(self.state.has_paired)
         self.assertIsNotNone(self.service.credentials)
 
+    @unittest_run_loop
+    async def test_pairing_no_pin(self):
+        self.handle = await pyatv.pair(self.conf, Protocol.Companion, self.loop)
+
+        await self.handle.begin()
+        with self.assertRaises(exceptions.PairingError):
+            await self.handle.finish()
+
     @unittest_run_loop
     async def test_pairing_with_bad_pin(self):
         self.handle = await pyatv.pair(self.conf, Protocol.Companion, self.loop)
diff --git a/tests/dmap/test_parser.py b/tests/dmap/test_parser.py
index 2f621947..0896eba4 100644
--- a/tests/dmap/test_parser.py
+++ b/tests/dmap/test_parser.py
@@ -28,6 +28,10 @@ def lookup_tag(name):
     return TEST_TAGS[name]
 
 
+def test_empty_data():
+    assert parser.parse(b"", lookup_tag) == []
+
+
 def test_parse_uint_of_various_lengths():
     in_data = (
         tags.uint8_tag("uuu8", 12)