Repository: XKNX/xknx
Pull request #647 (2021-03-30 06:38:15)

Bump pylint from 2.7.2 to 2.7.3
Bumps [pylint](https://github.com/PyCQA/pylint) from 2.7.2 to 2.7.3.
<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.7.3</h2>
<ul>
<li>
<p>Introduce logic for checking deprecated attributes in DeprecationMixin.</p>
</li>
<li>
<p>Reduce usage of blacklist/whitelist terminology. Notably, <code>extension-pkg-allow-list</code> is an
alternative to <code>extension-pkg-whitelist</code> and the message <code>blacklisted-name</code> is now emitted as
<code>disallowed-name</code>. The previous names are accepted to maintain backward compatibility.</p>
</li>
<li>
<p>Move deprecated checker to <code>DeprecatedMixin</code></p>
<p>Closes <a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/4086">#4086</a></p>
</li>
<li>
<p>Bump <code>astroid</code> version to <code>2.5.2</code></p>
</li>
<li>
<p>Fix false positive for <code>method-hidden</code> when using private attribute and method</p>
<p>Closes <a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/3936">#3936</a></p>
</li>
<li>
<p><code>use-symbolic-message-instead</code> now also works on legacy messages like <code>C0111</code> (<code>missing-docstring</code>).</p>
</li>
<li>
<p>Remove unwanted print to stdout from <code>_emit_no_member</code></p>
</li>
<li>
<p>Introduce a command-line option to specify pyreverse output directory</p>
<p>Closes <a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/4159">#4159</a></p>
</li>
<li>
<p>Fix issue with Enums and <code>class-attribute-naming-style=snake_case</code></p>
<p>Closes <a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/4149">#4149</a></p>
</li>
<li>
<p>Add <code>allowed-redefined-builtins</code> option for fine tuning <code>redefined-builtin</code> check.</p>
<p>Close <a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/3263">#3263</a></p>
</li>
<li>
<p>Fix issue when executing with <code>python -m pylint</code></p>
<p>Closes <a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/4161">#4161</a></p>
</li>
<li>
<p>Exempt <code>typing.TypedDict</code> from <code>too-few-public-methods</code> check.</p>
<p>Closes <a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/4180">#4180</a></p>
</li>
<li>
<p>Fix false-positive <code>no-member</code> for typed annotations without default value.</p>
<p>Closes <a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/3167">#3167</a></p>
</li>
<li>
<p>Add <code>--class-const-naming-style</code> for Enum constants and class variables annotated
with <code>typing.ClassVar</code></p>
<p>Closes <a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/4181">#4181</a></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.7.3?</h1>
<p>Release date: 2021-03-29</p>
<ul>
<li>
<p>Introduce logic for checking deprecated attributes in DeprecationMixin.</p>
</li>
<li>
<p>Reduce usage of blacklist/whitelist terminology. Notably, <code>extension-pkg-allow-list</code> is an
alternative to <code>extension-pkg-whitelist</code> and the message <code>blacklisted-name</code> is now emitted as
<code>disallowed-name</code>. The previous names are accepted to maintain backward compatibility.</p>
</li>
<li>
<p>Move deprecated checker to <code>DeprecatedMixin</code></p>
<p>Closes <a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/4086">#4086</a></p>
</li>
<li>
<p>Bump <code>astroid</code> version to <code>2.5.2</code></p>
</li>
<li>
<p>Fix false positive for <code>method-hidden</code> when using private attribute and method</p>
<p>Closes <a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/3936">#3936</a></p>
</li>
<li>
<p><code>use-symbolic-message-instead</code> now also works on legacy messages like <code>C0111</code> (<code>missing-docstring</code>).</p>
</li>
<li>
<p>Remove unwanted print to stdout from <code>_emit_no_member</code></p>
</li>
<li>
<p>Introduce a command-line option to specify pyreverse output directory</p>
<p>Closes <a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/4159">#4159</a></p>
</li>
<li>
<p>Fix issue with Enums and <code>class-attribute-naming-style=snake_case</code></p>
<p>Closes <a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/4149">#4149</a></p>
</li>
<li>
<p>Add <code>allowed-redefined-builtins</code> option for fine tuning <code>redefined-builtin</code> check.</p>
<p>Close <a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/3263">#3263</a></p>
</li>
<li>
<p>Fix issue when executing with <code>python -m pylint</code></p>
<p>Closes <a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/4161">#4161</a></p>
</li>
<li>
<p>Exempt <code>typing.TypedDict</code> from <code>too-few-public-methods</code> check.</p>
<p>Closes <a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/4180">#4180</a></p>
</li>
<li>
<p>Fix false-positive <code>no-member</code> for typed annotations without default value.</p>
<p>Closes <a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/3167">#3167</a></p>
</li>
<li>
<p>Add <code>--class-const-naming-style</code> for Enum constants and class variables annotated
with <code>typing.ClassVar</code></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/13dae7c5c6d16281f1415c88f845548d6cd9c823"><code>13dae7c</code></a> Prepare 2.7.3 release (<a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/4261">#4261</a>)</li>
<li><a href="https://github.com/PyCQA/pylint/commit/a37c643d54ea33285e4c916a296784593af0130c"><code>a37c643</code></a> Fix various problems with --import-graph filename parsing (<a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/4259">#4259</a>)</li>
<li><a href="https://github.com/PyCQA/pylint/commit/42bf3b0f4d2aad3e5b40153cf743021de635836d"><code>42bf3b0</code></a> Fix regession with sys.path filter (2)</li>
<li><a href="https://github.com/PyCQA/pylint/commit/c85cb41f65cde155663b0953569c90e8de8b6c1e"><code>c85cb41</code></a> Fix regression with sys.path filter (<a href="https://github-redirect.dependabot.com/PyCQA/pylint/issues/4258">#4258</a>)</li>
<li><a href="https://github.com/PyCQA/pylint/commit/95daecab4dece76e96e410033f6d659f283f3a57"><code>95daeca</code></a> Bump astroid version to 2.5.2</li>
<li><a href="https://github.com/PyCQA/pylint/commit/7905ec1f35d35aedb0a299598eebc9c98fe73f8a"><code>7905ec1</code></a> Fix false-positive for unused-import on class keyword arguments</li>
<li><a href="https://github.com/PyCQA/pylint/commit/12acc439bdbece347334b9e1efbdc7245da5001d"><code>12acc43</code></a> Fix a typo where 'msg =' was repeated twice</li>
<li><a href="https://github.com/PyCQA/pylint/commit/14f20e2d50b71d92893edda67c00054a840ee05f"><code>14f20e2</code></a> Import astroid with import x or from x import y but not both</li>
<li><a href="https://github.com/PyCQA/pylint/commit/d2db40c08433ca35dc9e5312e1d1b6404db65c33"><code>d2db40c</code></a> Redefining <strong>hash</strong> without redefining <strong>eq</strong> is suspicious</li>
<li><a href="https://github.com/PyCQA/pylint/commit/cd4168366b79a7782287e0b7162fbfe4f67535f8"><code>cd41683</code></a> Fix classes do not defining 4 ordering comparison methods</li>
<li>Additional commits viewable in <a href="https://github.com/PyCQA/pylint/compare/pylint-2.7.2...pylint-2.7.3">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.2&new-version=2.7.3)](https://dependabot.com/compatibility-score/?dependency-name=pylint&package-manager=pip&previous-version=2.7.2&new-version=2.7.3)

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)
[//]: # (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 use these labels` will set the current labels as the default for future PRs for this repo and language
- `@dependabot use these reviewers` will set the current reviewers as the default for future PRs for this repo and language
- `@dependabot use these assignees` will set the current assignees as the default for future PRs for this repo and language
- `@dependabot use this milestone` will set the current milestone as the default for future PRs for this repo and language
- `@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 your Dependabot [dashboard](https://app.dependabot.com):
- Update frequency (including time of day and day of week)
- Pull request limits (per update run and/or open at any time)
- Out-of-range updates (receive only lockfile updates, if desired)
- Security updates (receive only security updates, if desired)



</details>

coveralls: 
[![Coverage Status](https://coveralls.io/builds/38382944/badge)](https://coveralls.io/builds/38382944)

Coverage remained the same at 94.743% when pulling **d1cdda3b138e1f90ee33099500c9c7cdc6c42d3f on dependabot/pip/pylint-2.7.3** into **87d20e373696ba49c062a4297545cdc0f8f9726e on main**.


Patch:
diff --git a/xknx/io/request_response.py b/xknx/io/request_response.py
index bef39fe9..08846357 100644
--- a/xknx/io/request_response.py
+++ b/xknx/io/request_response.py
@@ -44,7 +44,7 @@ class RequestResponse:
     async def start(self) -> None:
         """Start. Send request and wait for an answer."""
         callb = self.udpclient.register_callback(
-            self.response_rec_callback, [self.awaited_response_class.service_type]
+            self.response_rec_callback, [self.awaited_response_class.SERVICE_TYPE]
         )
         await self.send_request()
 
diff --git a/xknx/knxip/body.py b/xknx/knxip/body.py
index 542c501c..96d721af 100644
--- a/xknx/knxip/body.py
+++ b/xknx/knxip/body.py
@@ -15,7 +15,7 @@ logger = logging.getLogger("xknx.log")
 class KNXIPBody(ABC):
     """Base class for all KNX/IP bodies."""
 
-    service_type: ClassVar[KNXIPServiceType] = cast(KNXIPServiceType, None)
+    SERVICE_TYPE: ClassVar[KNXIPServiceType] = cast(KNXIPServiceType, None)
 
     def __init__(self, xknx: "XKNX"):
         """Initialize KNXIPBody object."""
diff --git a/xknx/knxip/connect_request.py b/xknx/knxip/connect_request.py
index 090139a2..9c879374 100644
--- a/xknx/knxip/connect_request.py
+++ b/xknx/knxip/connect_request.py
@@ -20,8 +20,7 @@ class ConnectRequest(KNXIPBody):
 
     # pylint: disable=too-many-instance-attributes
 
-    service_type = KNXIPServiceType.CONNECT_REQUEST
-
+    SERVICE_TYPE = KNXIPServiceType.CONNECT_REQUEST
     CRI_LENGTH = 4
 
     def __init__(
diff --git a/xknx/knxip/connect_response.py b/xknx/knxip/connect_response.py
index 7190cc39..95519f22 100644
--- a/xknx/knxip/connect_response.py
+++ b/xknx/knxip/connect_response.py
@@ -23,8 +23,7 @@ class ConnectResponse(KNXIPBodyResponse):
 
     # pylint: disable=too-many-instance-attributes
 
-    service_type = KNXIPServiceType.CONNECT_RESPONSE
-
+    SERVICE_TYPE = KNXIPServiceType.CONNECT_RESPONSE
     CRD_LENGTH = 4
 
     def __init__(
diff --git a/xknx/knxip/connectionstate_request.py b/xknx/knxip/connectionstate_request.py
index c59ffe4c..9c759fa1 100644
--- a/xknx/knxip/connectionstate_request.py
+++ b/xknx/knxip/connectionstate_request.py
@@ -19,8 +19,7 @@ class ConnectionStateRequest(KNXIPBody):
     """Representation of a KNX Connection State Request."""
 
     # pylint: disable=too-many-instance-attributes
-
-    service_type = KNXIPServiceType.CONNECTIONSTATE_REQUEST
+    SERVICE_TYPE = KNXIPServiceType.CONNECTIONSTATE_REQUEST
 
     def __init__(
         self,
diff --git a/xknx/knxip/connectionstate_response.py b/xknx/knxip/connectionstate_response.py
index cca623a3..f1d10dae 100644
--- a/xknx/knxip/connectionstate_response.py
+++ b/xknx/knxip/connectionstate_response.py
@@ -20,8 +20,7 @@ class ConnectionStateResponse(KNXIPBodyResponse):
     """Representation of a KNX Connection State Response."""
 
     # pylint: disable=too-many-instance-attributes
-
-    service_type = KNXIPServiceType.CONNECTIONSTATE_RESPONSE
+    SERVICE_TYPE = KNXIPServiceType.CONNECTIONSTATE_RESPONSE
 
     def __init__(
         self,
diff --git a/xknx/knxip/disconnect_request.py b/xknx/knxip/disconnect_request.py
index a73e7fec..11fb3e45 100644
--- a/xknx/knxip/disconnect_request.py
+++ b/xknx/knxip/disconnect_request.py
@@ -19,8 +19,7 @@ class DisconnectRequest(KNXIPBody):
     """Representation of a KNX Disconnect Request."""
 
     # pylint: disable=too-many-instance-attributes
-
-    service_type = KNXIPServiceType.DISCONNECT_REQUEST
+    SERVICE_TYPE = KNXIPServiceType.DISCONNECT_REQUEST
 
     def __init__(
         self,
diff --git a/xknx/knxip/disconnect_response.py b/xknx/knxip/disconnect_response.py
index 730fbb85..1af65d91 100644
--- a/xknx/knxip/disconnect_response.py
+++ b/xknx/knxip/disconnect_response.py
@@ -20,8 +20,7 @@ class DisconnectResponse(KNXIPBodyResponse):
     """Representation of a KNX Disconnect Response."""
 
     # pylint: disable=too-many-instance-attributes
-
-    service_type = KNXIPServiceType.DISCONNECT_RESPONSE
+    SERVICE_TYPE = KNXIPServiceType.DISCONNECT_RESPONSE
 
     def __init__(
         self,
diff --git a/xknx/knxip/knxip.py b/xknx/knxip/knxip.py
index f555c31c..1f55a47d 100644
--- a/xknx/knxip/knxip.py
+++ b/xknx/knxip/knxip.py
@@ -74,7 +74,7 @@ class KNXIPFrame:
     def init_from_body(knxip_body: KNXIPBody) -> "KNXIPFrame":
         """Return KNXIPFrame from KNXIPBody."""
         knxipframe = KNXIPFrame(knxip_body.xknx)
-        knxipframe.header.service_type_ident = knxip_body.__class__.service_type
+        knxipframe.header.service_type_ident = knxip_body.__class__.SERVICE_TYPE
         knxipframe.body = knxip_body
         knxipframe.header.set_length(knxip_body)
         return knxipframe
diff --git a/xknx/knxip/routing_indication.py b/xknx/knxip/routing_indication.py
index 25ee9415..d8623b90 100644
--- a/xknx/knxip/routing_indication.py
+++ b/xknx/knxip/routing_indication.py
@@ -21,8 +21,7 @@ class RoutingIndication(KNXIPBody):
     """Representation of a KNX Routing Indication."""
 
     # pylint: disable=too-many-instance-attributes
-
-    service_type = KNXIPServiceType.ROUTING_INDICATION
+    SERVICE_TYPE = KNXIPServiceType.ROUTING_INDICATION
 
     def __init__(self, xknx: "XKNX", cemi: Optional[CEMIFrame] = None):
         """Initialize SearchRequest object."""
diff --git a/xknx/knxip/search_request.py b/xknx/knxip/search_request.py
index 4ebc5dc6..bee329b6 100644
--- a/xknx/knxip/search_request.py
+++ b/xknx/knxip/search_request.py
@@ -17,8 +17,7 @@ class SearchRequest(KNXIPBody):
     """Representation of a KNX Connect Request."""
 
     # pylint: disable=too-many-instance-attributes
-
-    service_type = KNXIPServiceType.SEARCH_REQUEST
+    SERVICE_TYPE = KNXIPServiceType.SEARCH_REQUEST
 
     def __init__(self, xknx: "XKNX", discovery_endpoint: Optional[HPAI] = None):
         """Initialize SearchRequest object."""
diff --git a/xknx/knxip/search_response.py b/xknx/knxip/search_response.py
index 7d2c1722..600ef318 100644
--- a/xknx/knxip/search_response.py
+++ b/xknx/knxip/search_response.py
@@ -21,8 +21,7 @@ class SearchResponse(KNXIPBody):
     """Representation of a KNX Search Response."""
 
     # pylint: disable=too-many-instance-attributes
-
-    service_type = KNXIPServiceType.SEARCH_RESPONSE
+    SERVICE_TYPE = KNXIPServiceType.SEARCH_RESPONSE
 
     def __init__(self, xknx: "XKNX", control_endpoint: HPAI = HPAI()):
         """Initialize SearchResponse object."""
diff --git a/xknx/knxip/tunnelling_ack.py b/xknx/knxip/tunnelling_ack.py
index 8dc1f879..3681fec8 100644
--- a/xknx/knxip/tunnelling_ack.py
+++ b/xknx/knxip/tunnelling_ack.py
@@ -20,9 +20,7 @@ class TunnellingAck(KNXIPBodyResponse):
     """Representation of a KNX Tunnelling Ack."""
 
     # pylint: disable=too-many-instance-attributes
-
-    service_type = KNXIPServiceType.TUNNELLING_ACK
-
+    SERVICE_TYPE = KNXIPServiceType.TUNNELLING_ACK
     BODY_LENGTH = 4
 
     def __init__(
diff --git a/xknx/knxip/tunnelling_request.py b/xknx/knxip/tunnelling_request.py
index 12848ce8..1206a683 100644
--- a/xknx/knxip/tunnelling_request.py
+++ b/xknx/knxip/tunnelling_request.py
@@ -22,9 +22,7 @@ class TunnellingRequest(KNXIPBody):
     """Representation of a KNX Tunnelling Request."""
 
     # pylint: disable=too-many-instance-attributes
-
-    service_type = KNXIPServiceType.TUNNELLING_REQUEST
-
+    SERVICE_TYPE = KNXIPServiceType.TUNNELLING_REQUEST
     HEADER_LENGTH = 4
 
     def __init__(
diff --git a/xknx/telegram/apci.py b/xknx/telegram/apci.py
index 1e9d17c5..890d6f53 100644
--- a/xknx/telegram/apci.py
+++ b/xknx/telegram/apci.py
@@ -103,7 +103,7 @@ class APCI(ABC):
     This base class is only the interface for the derived classes.
     """
 
-    code: ClassVar[Union[APCIService, APCIUserService, APCIExtendedService]] = cast(
+    CODE: ClassVar[Union[APCIService, APCIUserService, APCIExtendedService]] = cast(
         APCIService, None
     )
 
@@ -211,7 +211,7 @@ class GroupValueRead(APCI):
     Does not have any payload.
     """
 
-    code = APCIService.GROUP_READ
+    CODE = APCIService.GROUP_READ
 
     def calculated_length(self) -> int:
         """Get length of APCI payload."""
@@ -225,7 +225,7 @@ class GroupValueRead(APCI):
 
     def to_knx(self) -> bytes:
         """Serialize to KNX/IP raw data."""
-        return encode_cmd_and_payload(self.code)
+        return encode_cmd_and_payload(self.CODE)
 
     def __str__(self) -> str:
         """Return object as readable string."""
@@ -239,7 +239,7 @@ class GroupValueWrite(APCI):
     Takes a value (DPT) as payload.
     """
 
-    code = APCIService.GROUP_WRITE
+    CODE = APCIService.GROUP_WRITE
 
     def __init__(self, value: Optional[Union[DPTBinary, DPTArray]] = None) -> None:
         """Initialize a new instance of GroupValueWrite."""
@@ -263,10 +263,10 @@ class GroupValueWrite(APCI):
     def to_knx(self) -> bytes:
         """Serialize to KNX/IP raw data."""
         if isinstance(self.value, DPTBinary):
-            return encode_cmd_and_payload(self.code, encoded_payload=self.value.value)
+            return encode_cmd_and_payload(self.CODE, encoded_payload=self.value.value)
         if isinstance(self.value, DPTArray):
             return encode_cmd_and_payload(
-                self.code, appended_payload=bytes(self.value.value)
+                self.CODE, appended_payload=bytes(self.value.value)
             )
         raise TypeError()
 
@@ -282,7 +282,7 @@ class GroupValueResponse(APCI):
     Takes a value (DPT) as payload.
     """
 
-    code = APCIService.GROUP_RESPONSE
+    CODE = APCIService.GROUP_RESPONSE
 
     def __init__(self, value: Optional[Union[DPTBinary, DPTArray]] = None) -> None:
         """Initialize a new instance of GroupValueResponse."""
@@ -306,10 +306,10 @@ class GroupValueResponse(APCI):
     def to_knx(self) -> bytes:
         """Serialize to KNX/IP raw data."""
         if isinstance(self.value, DPTBinary):
-            return encode_cmd_and_payload(self.code, encoded_payload=self.value.value)
+            return encode_cmd_and_payload(self.CODE, encoded_payload=self.value.value)
         if isinstance(self.value, DPTArray):
             return encode_cmd_and_payload(
-                self.code, appended_payload=bytes(self.value.value)
+                self.CODE, appended_payload=bytes(self.value.value)
             )
         raise TypeError()
 
@@ -325,7 +325,7 @@ class IndividualAddressWrite(APCI):
     Payload contains the serial number and (new) address of the device.
     """
 
-    code = APCIService.INDIVIDUAL_ADDRESS_WRITE
+    CODE = APCIService.INDIVIDUAL_ADDRESS_WRITE
 
     def __init__(
         self,
@@ -350,7 +350,7 @@ class IndividualAddressWrite(APCI):
     def to_knx(self) -> bytes:
         """Serialize to KNX/IP raw data."""
         return encode_cmd_and_payload(
-            self.code, appended_payload=bytes(self.address.to_knx())
+            self.CODE, appended_payload=bytes(self.address.to_knx())
         )
 
     def __str__(self) -> str:
@@ -361,7 +361,7 @@ class IndividualAddressWrite(APCI):
 class IndividualAddressRead(APCI):
     """IndividualAddressRead service."""
 
-    code = APCIService.INDIVIDUAL_ADDRESS_READ
+    CODE = APCIService.INDIVIDUAL_ADDRESS_READ
 
     def calculated_length(self) -> int:
         """Get length of APCI payload."""
@@ -375,7 +375,7 @@ class IndividualAddressRead(APCI):
 
     def to_knx(self) -> bytes:
         """Serialize to KNX/IP raw data."""
-        return encode_cmd_and_payload(self.code)
+        return encode_cmd_and_payload(self.CODE)
 
     def __str__(self) -> str:
         """Return object as readable string."""
@@ -390,7 +390,7 @@ class IndividualAddressResponse(APCI):
     response address.
     """
 
-    code = APCIService.INDIVIDUAL_ADDRESS_RESPONSE
+    CODE = APCIService.INDIVIDUAL_ADDRESS_RESPONSE
 
     def calculated_length(self) -> int:
         """Get length of APCI payload."""
@@ -404,7 +404,7 @@ class IndividualAddressResponse(APCI):
 
     def to_knx(self) -> bytes:
         """Serialize to KNX/IP raw data."""
-        return encode_cmd_and_payload(self.code)
+        return encode_cmd_and_payload(self.CODE)
 
     def __str__(self) -> str:
         """Return object as readable string."""
@@ -418,7 +418,7 @@ class ADCRead(APCI):
     Payload contains the channel and number of samples to take.
     """
 
-    code = APCIService.ADC_READ
+    CODE = APCIService.ADC_READ
 
     def __init__(self, channel: int = 0, count: int = 0) -> None:
         """Initialize a new instance of ADCRead."""
@@ -440,7 +440,7 @@ class ADCRead(APCI):
         payload = struct.pack("!BB", self.channel, self.count)
 
         return encode_cmd_and_payload(
-            self.code, encoded_payload=payload[0], appended_payload=payload[1:]
+            self.CODE, encoded_payload=payload[0], appended_payload=payload[1:]
         )
 
     def __str__(self) -> str:
@@ -455,7 +455,7 @@ class ADCResponse(APCI):
     Payload contains the channel, number of samples and value.
     """
 
-    code = APCIService.ADC_RESPONSE
+    CODE = APCIService.ADC_RESPONSE
 
     def __init__(self, channel: int = 0, count: int = 0, value: int = 0) -> None:
         """Initialize a new instance of ADCResponse."""
@@ -478,7 +478,7 @@ class ADCResponse(APCI):
         payload = struct.pack("!BBH", self.channel, self.count, self.value)
 
         return encode_cmd_and_payload(
-            self.code, encoded_payload=payload[0], appended_payload=payload[1:]
+            self.CODE, encoded_payload=payload[0], appended_payload=payload[1:]
         )
 
     def __str__(self) -> str:
@@ -493,7 +493,7 @@ class MemoryRead(APCI):
     Payload indicates address (64 KiB) and count (1-63 bytes).
     """
 
-    code = APCIService.MEMORY_READ
+    CODE = APCIService.MEMORY_READ
 
     def __init__(self, address: int = 0, count: int = 0) -> None:
         """Initialize a new instance of MemoryRead."""
@@ -520,7 +520,7 @@ class MemoryRead(APCI):
         payload = struct.pack("!BH", self.count, self.address)
 
         return encode_cmd_and_payload(
-            self.code, encoded_payload=payload[0], appended_payload=payload[1:]
+            self.CODE, encoded_payload=payload[0], appended_payload=payload[1:]
         )
 
     def __str__(self) -> str:
@@ -535,7 +535,7 @@ class MemoryWrite(APCI):
     Payload indicates address (64 KiB), count (1-63 bytes) and data.
     """
 
-    code = APCIService.MEMORY_WRITE
+    CODE = APCIService.MEMORY_WRITE
 
     def __init__(
         self, address: int = 0, count: int = 0, data: Optional[bytes] = None
@@ -572,7 +572,7 @@ class MemoryWrite(APCI):
         payload = struct.pack(f"!BH{size}s", self.count, self.address, self.data)
 
         return encode_cmd_and_payload(
-            self.code, encoded_payload=payload[0], appended_payload=payload[1:]
+            self.CODE, encoded_payload=payload[0], appended_payload=payload[1:]
         )
 
     def __str__(self) -> str:
@@ -587,7 +587,7 @@ class MemoryResponse(APCI):
     Payload indicates address (64 KiB), count (1-63 bytes) and data.
     """
 
-    code = APCIService.MEMORY_RESPONSE
+    CODE = APCIService.MEMORY_RESPONSE
 
     def __init__(
         self, address: int = 0, count: int = 0, data: Optional[bytes] = None
@@ -624,7 +624,7 @@ class MemoryResponse(APCI):
         payload = struct.pack(f"!BH{size}s", self.count, self.address, self.data)
 
         return encode_cmd_and_payload(
-            self.code, encoded_payload=payload[0], appended_payload=payload[1:]
+            self.CODE, encoded_payload=payload[0], appended_payload=payload[1:]
         )
 
     def __str__(self) -> str:
@@ -639,7 +639,7 @@ class DeviceDescriptorRead(APCI):
     Payload contains the descriptor.
     """
 
-    code = APCIService.DEVICE_DESCRIPTOR_READ
+    CODE = APCIService.DEVICE_DESCRIPTOR_READ
 
     def __init__(self, descriptor: int = 0) -> None:
         """Initialize a new instance of DeviceDescriptorRead."""
@@ -658,7 +658,7 @@ class DeviceDescriptorRead(APCI):
         if self.descriptor < 0 or self.descriptor >= 2 ** 6:
             raise ConversionError("Descriptor out of range.")
 
-        return encode_cmd_and_payload(self.code, encoded_payload=self.descriptor)
+        return encode_cmd_and_payload(self.CODE, encoded_payload=self.descriptor)
 
     def __str__(self) -> str:
         """Return object as readable string."""
@@ -672,7 +672,7 @@ class DeviceDescriptorResponse(APCI):
     Payload contains the descriptor and value.
     """
 
-    code = APCIService.DEVICE_DESCRIPTOR_RESPONSE
+    CODE = APCIService.DEVICE_DESCRIPTOR_RESPONSE
 
     def __init__(self, descriptor: int = 0, value: int = 0) -> None:
         """Initialize a new instance of DeviceDescriptorResponse."""
@@ -697,7 +697,7 @@ class DeviceDescriptorResponse(APCI):
         payload = struct.pack("!H", self.value)
 
         return encode_cmd_and_payload(
-            self.code, encoded_payload=self.descriptor, appended_payload=payload
+            self.CODE, encoded_payload=self.descriptor, appended_payload=payload
         )
 
     def __str__(self) -> str:
@@ -714,7 +714,7 @@ class Restart(APCI):
     Does not take any payload.
     """
 
-    code = APCIService.RESTART
+    CODE = APCIService.RESTART
 
     def calculated_length(self) -> int:
         """Get length of APCI payload."""
@@ -728,7 +728,7 @@ class Restart(APCI):
 
     def to_knx(self) -> bytes:
         """Serialize to KNX/IP raw data."""
-        return encode_cmd_and_payload(self.code)
+        return encode_cmd_and_payload(self.CODE)
 
     def __str__(self) -> str:
         """Return object as readable string."""
@@ -742,7 +742,7 @@ class UserMemoryRead(APCI):
     Payload indicates address (1 MiB) and count (1-15 bytes).
     """
 
-    code = APCIUserService.USER_MEMORY_READ
+    CODE = APCIUserService.USER_MEMORY_READ
 
     def __init__(self, address: int = 0, count: int = 0) -> None:
         """Initialize a new instance of UserMemoryRead."""
@@ -772,7 +772,7 @@ class UserMemoryRead(APCI):
 
         payload = struct.pack("!BH", byte0, address)
 
-        return encode_cmd_and_payload(self.code, appended_payload=payload)
+        return encode_cmd_and_payload(self.CODE, appended_payload=payload)
 
     def __str__(self) -> str:
         """Return object as readable string."""
@@ -786,7 +786,7 @@ class UserMemoryWrite(APCI):
     Payload indicates address (1 MiB), count and data.
     """
 
-    code = APCIUserService.USER_MEMORY_WRITE
+    CODE = APCIUserService.USER_MEMORY_WRITE
 
     def __init__(
         self, address: int = 0, count: int = 0, data: Optional[bytes] = None
@@ -826,7 +826,7 @@ class UserMemoryWrite(APCI):
         size = len(self.data)
         payload = struct.pack(f"!BH{size}s", byte0, address, self.data)
 
-        return encode_cmd_and_payload(self.code, appended_payload=payload)
+        return encode_cmd_and_payload(self.CODE, appended_payload=payload)
 
     def __str__(self) -> str:
         """Return object as readable string."""
@@ -840,7 +840,7 @@ class UserMemoryResponse(APCI):
     Payload indicates address (1 MiB), count and data.
     """
 
-    code = APCIUserService.USER_MEMORY_RESPONSE
+    CODE = APCIUserService.USER_MEMORY_RESPONSE
 
     def __init__(
         self, address: int = 0, count: int = 0, data: Optional[bytes] = None
@@ -880,7 +880,7 @@ class UserMemoryResponse(APCI):
         size = len(self.data)
         payload = struct.pack(f"!BH{size}s", byte0, address, self.data)
 
-        return encode_cmd_and_payload(self.code, appended_payload=payload)
+        return encode_cmd_and_payload(self.CODE, appended_payload=payload)
 
     def __str__(self) -> str:
         """Return object as readable string."""
@@ -890,7 +890,7 @@ class UserMemoryResponse(APCI):
 class UserManufacturerInfoRead(APCI):
     """UserManufacturerInfoRead service."""
 
-    code = APCIUserService.USER_MANUFACTURER_INFO_READ
+    CODE = APCIUserService.USER_MANUFACTURER_INFO_READ
 
     def calculated_length(self) -> int:
         """Get length of APCI payload."""
@@ -905,7 +905,7 @@ class UserManufacturerInfoRead(APCI):
     def to_knx(self) -> bytes:
         """Serialize to KNX/IP raw data."""
 
-        return encode_cmd_and_payload(self.code)
+        return encode_cmd_and_payload(self.CODE)
 
     def __str__(self) -> str:
         """Return object as readable string."""
@@ -915,7 +915,7 @@ class UserManufacturerInfoRead(APCI):
 class UserManufacturerInfoResponse(APCI):
     """UserManufacturerInfoResponse service."""
 
-    code = APCIUserService.USER_MANUFACTURER_INFO_RESPONSE
+    CODE = APCIUserService.USER_MANUFACTURER_INFO_RESPONSE
 
     def __init__(self, manufacturer_id: int = 0, data: Optional[bytes] = None) -> None:
         """Initialize a new instance of UserManufacturerInfoResponse."""
@@ -937,7 +937,7 @@ class UserManufacturerInfoResponse(APCI):
         """Serialize to KNX/IP raw data."""
         payload = struct.pack("!B2s", self.manufacturer_id, self.data)
 
-        return encode_cmd_and_payload(self.code, appended_payload=payload)
+        return encode_cmd_and_payload(self.CODE, appended_payload=payload)
 
     def __str__(self) -> str:
         """Return object as readable string."""
@@ -947,7 +947,7 @@ class UserManufacturerInfoResponse(APCI):
 class FunctionPropertyCommand(APCI):
     """FunctionPropertyCommand service."""
 
-    code = APCIUserService.FUNCTION_PROPERTY_COMMAND
+    CODE = APCIUserService.FUNCTION_PROPERTY_COMMAND
 
     def __init__(
         self, object_index: int = 0, property_id: int = 0, data: Optional[bytes] = None
@@ -979,7 +979,7 @@ class FunctionPropertyCommand(APCI):
             f"!BB{size}s", self.object_index, self.property_id, self.data
         )
 
-        return encode_cmd_and_payload(self.code, appended_payload=payload)
+        return encode_cmd_and_payload(self.CODE, appended_payload=payload)
 
     def __str__(self) -> str:
         """Return object as readable string."""
@@ -989,7 +989,7 @@ class FunctionPropertyCommand(APCI):
 class FunctionPropertyStateRead(APCI):
     """FunctionPropertyStateRead service."""
 
-    code = APCIUserService.FUNCTION_PROPERTY_STATE_READ
+    CODE = APCIUserService.FUNCTION_PROPERTY_STATE_READ
 
     def __init__(
         self, object_index: int = 0, property_id: int = 0, data: Optional[bytes] = None
@@ -1021,7 +1021,7 @@ class FunctionPropertyStateRead(APCI):
             f"!BB{size}s", self.object_index, self.property_id, self.data
         )
 
-        return encode_cmd_and_payload(self.code, appended_payload=payload)
+        return encode_cmd_and_payload(self.CODE, appended_payload=payload)
 
     def __str__(self) -> str:
         """Return object as readable string."""
@@ -1031,7 +1031,7 @@ class FunctionPropertyStateRead(APCI):
 class FunctionPropertyStateResponse(APCI):
     """FunctionPropertyStateResponse service."""
 
-    code = APCIUserService.FUNCTION_PROPERTY_STATE_READ
+    CODE = APCIUserService.FUNCTION_PROPERTY_STATE_READ
 
     def __init__(
         self,
@@ -1075,7 +1075,7 @@ class FunctionPropertyStateResponse(APCI):
             self.data,
         )
 
-        return encode_cmd_and_payload(self.code, appended_payload=payload)
+        return encode_cmd_and_payload(self.CODE, appended_payload=payload)
 
     def __str__(self) -> str:
         """Return object as readable string."""
@@ -1085,7 +1085,7 @@ class FunctionPropertyStateResponse(APCI):
 class AuthorizeRequest(APCI):
     """AuthorizeRequest service."""
 
-    code = APCIExtendedService.AUTHORIZE_REQUEST
+    CODE = APCIExtendedService.AUTHORIZE_REQUEST
 
     def __init__(self, key: int = 0) -> None:
         """Initialize a new instance of AuthorizeRequest."""
@@ -1103,7 +1103,7 @@ class AuthorizeRequest(APCI):
         """Serialize to KNX/IP raw data."""
         payload = struct.pack("!BI", 0, self.key)
 
-        return encode_cmd_and_payload(self.code, appended_payload=payload)
+        return encode_cmd_and_payload(self.CODE, appended_payload=payload)
 
     def __str__(self) -> str:
         """Return object as readable string."""
@@ -1113,7 +1113,7 @@ class AuthorizeRequest(APCI):
 class AuthorizeResponse(APCI):
     """AuthorizeResponse service."""
 
-    code = APCIExtendedService.AUTHORIZE_RESPONSE
+    CODE = APCIExtendedService.AUTHORIZE_RESPONSE
 
     def __init__(self, level: int = 0) -> None:
         """Initialize a new instance of AuthorizeResponse."""
@@ -1131,7 +1131,7 @@ class AuthorizeResponse(APCI):
         """Serialize to KNX/IP raw data."""
         payload = struct.pack("!B", self.level)
 
-        return encode_cmd_and_payload(self.code, appended_payload=payload)
+        return encode_cmd_and_payload(self.CODE, appended_payload=payload)
 
     def __str__(self) -> str:
         """Return object as readable string."""
@@ -1145,7 +1145,7 @@ class PropertyValueRead(APCI):
     Payload indicates object, property, count and start.
     """
 
-    code = APCIExtendedService.PROPERTY_VALUE_READ
+    CODE = APCIExtendedService.PROPERTY_VALUE_READ
 
     def __init__(
         self,
@@ -1188,7 +1188,7 @@ class PropertyValueRead(APCI):
             self.start_index,
         )
 
-        return encode_cmd_and_payload(self.code, appended_payload=payload)
+        return encode_cmd_and_payload(self.CODE, appended_payload=payload)
 
     def __str__(self) -> str:
         """Return object as readable string."""
@@ -1207,7 +1207,7 @@ class PropertyValueWrite(APCI):
     Payload indicates object, property, count, start and data itself.
     """
 
-    code = APCIExtendedService.PROPERTY_VALUE_WRITE
+    CODE = APCIExtendedService.PROPERTY_VALUE_WRITE
 
     def __init__(
         self,
@@ -1248,7 +1248,7 @@ class PropertyValueWrite(APCI):
             self.data,
         )
 
-        return encode_cmd_and_payload(self.code, appended_payload=payload)
+        return encode_cmd_and_payload(self.CODE, appended_payload=payload)
 
     def from_knx(self, raw: bytes) -> None:
         """Parse/deserialize from KNX/IP raw data."""
@@ -1287,7 +1287,7 @@ class PropertyValueResponse(APCI):
     the payload depends on the data.
     """
 
-    code = APCIExtendedService.PROPERTY_VALUE_RESPONSE
+    CODE = APCIExtendedService.PROPERTY_VALUE_RESPONSE
 
     def __init__(
         self,
@@ -1343,7 +1343,7 @@ class PropertyValueResponse(APCI):
             self.data,
         )
 
-        return encode_cmd_and_payload(self.code, appended_payload=payload)
+        return encode_cmd_and_payload(self.CODE, appended_payload=payload)
 
     def __str__(self) -> str:
         """Return object as readable string."""
@@ -1362,7 +1362,7 @@ class PropertyValueResponse(APCI):
 class PropertyDescriptionRead(APCI):
     """PropertyDescriptionRead service."""
 
-    code = APCIExtendedService.PROPERTY_DESCRIPTION_READ
+    CODE = APCIExtendedService.PROPERTY_DESCRIPTION_READ
 
     def __init__(
         self, object_index: int = 0, property_id: int = 0, property_index: int = 0
@@ -1388,7 +1388,7 @@ class PropertyDescriptionRead(APCI):
             "!BBB", self.object_index, self.property_id, self.property_index
         )
 
-        return encode_cmd_and_payload(self.code, appended_payload=payload)
+        return encode_cmd_and_payload(self.CODE, appended_payload=payload)
 
     def __str__(self) -> str:
         """Return object as readable string."""
@@ -1398,7 +1398,7 @@ class PropertyDescriptionRead(APCI):
 class PropertyDescriptionResponse(APCI):
     """PropertyDescriptionResponse service."""
 
-    code = APCIExtendedService.PROPERTY_DESCRIPTION_RESPONSE
+    CODE = APCIExtendedService.PROPERTY_DESCRIPTION_RESPONSE
 
     def __init__(
         self,
@@ -1449,7 +1449,7 @@ class PropertyDescriptionResponse(APCI):
             self.access,
         )
 
-        return encode_cmd_and_payload(self.code, appended_payload=payload)
+        return encode_cmd_and_payload(self.CODE, appended_payload=payload)
 
     def __str__(self) -> str:
         """Return object as readable string."""
@@ -1459,7 +1459,7 @@ class PropertyDescriptionResponse(APCI):
 class IndividualAddressSerialRead(APCI):
     """IndividualAddressSerialRead service."""
 
-    code = APCIExtendedService.INDIVIDUAL_ADDRESS_SERIAL_READ
+    CODE = APCIExtendedService.INDIVIDUAL_ADDRESS_SERIAL_READ
 
     def __init__(self, serial: Optional[bytes] = None) -> None:
         """Initialize a new instance of PropertyDescriptionRead."""
@@ -1483,7 +1483,7 @@ class IndividualAddressSerialRead(APCI):
 
         payload = struct.pack("!6s", self.serial)
 
-        return encode_cmd_and_payload(self.code, appended_payload=payload)
+        return encode_cmd_and_payload(self.CODE, appended_payload=payload)
 
     def __str__(self) -> str:
         """Return object as readable string."""
@@ -1493,7 +1493,7 @@ class IndividualAddressSerialRead(APCI):
 class IndividualAddressSerialResponse(APCI):
     """IndividualAddressSerialResponse service."""
 
-    code = APCIExtendedService.INDIVIDUAL_ADDRESS_SERIAL_RESPONSE
+    CODE = APCIExtendedService.INDIVIDUAL_ADDRESS_SERIAL_RESPONSE
 
     def __init__(
         self,
@@ -1527,7 +1527,7 @@ class IndividualAddressSerialResponse(APCI):
         address_high, address_low = self.address.to_knx()
         payload = struct.pack("!6sBBH", self.serial, address_high, address_low, 0)
 
-        return encode_cmd_and_payload(self.code, appended_payload=payload)
+        return encode_cmd_and_payload(self.CODE, appended_payload=payload)
 
     def __str__(self) -> str:
         """Return object as readable string."""
@@ -1537,7 +1537,7 @@ class IndividualAddressSerialResponse(APCI):
 class IndividualAddressSerialWrite(APCI):
     """IndividualAddressSerialWrite service."""
 
-    code = APCIExtendedService.INDIVIDUAL_ADDRESS_SERIAL_WRITE
+    CODE = APCIExtendedService.INDIVIDUAL_ADDRESS_SERIAL_WRITE
 
     def __init__(
         self,
@@ -1571,7 +1571,7 @@ class IndividualAddressSerialWrite(APCI):
         address_high, address_low = self.address.to_knx()
         payload = struct.pack("!6sBBI", self.serial, address_high, address_low, 0)
 
-        return encode_cmd_and_payload(self.code, appended_payload=payload)
+        return encode_cmd_and_payload(self.CODE, appended_payload=payload)
 
     def __str__(self) -> str:
         """Return object as readable string."""


Test patch:
diff --git a/requirements/testing.txt b/requirements/testing.txt
index af66301d..b3c94c39 100644
--- a/requirements/testing.txt
+++ b/requirements/testing.txt
@@ -5,7 +5,7 @@ coveralls==3.0.1
 flake8==3.9.0
 flake8-isort==4.0.0
 pydocstyle==6.0.0
-pylint==2.7.2
+pylint==2.7.3
 pylint-strict-informational==0.1
 pytest==6.2.2
 pytest-cov==2.11.1
diff --git a/test/knxip_tests/body_test.py b/test/knxip_tests/body_test.py
index 5f500201..647e771f 100644
--- a/test/knxip_tests/body_test.py
+++ b/test/knxip_tests/body_test.py
@@ -17,11 +17,11 @@ class Test_KNXIPBody(unittest.TestCase):
     def test_body_attributes(self):
         """Test attributes of KNXIPBody base class."""
         body = KNXIPBody(self.xknx)
-        self.assertTrue(hasattr(body, "service_type"))
+        self.assertTrue(hasattr(body, "SERVICE_TYPE"))
 
     @patch.multiple(KNXIPBodyResponse, __abstractmethods__=set())
     def test_response_attributes(self):
         """Test attributes of KNXIPBodyResponse base class."""
         response = KNXIPBodyResponse(self.xknx)
-        self.assertTrue(hasattr(response, "service_type"))
+        self.assertTrue(hasattr(response, "SERVICE_TYPE"))
         self.assertTrue(hasattr(response, "status_code"))