Repository: pynamodb/PynamoDB

Issue:
v5.2.0 breaking change? AttributeError: type object 'Meta' has no attribute 'read_capacity_units'
The release of 5.2.0 broke GlobalSecondaryIndex syntax that worked on 5.1.0. Requesting to add a note about it in release notes for 5.2.0


## Broken syntax in 5.2.0, but working in 5.1.0
```
class UserRangeKey(GlobalSecondaryIndex):
    class Meta:
        index_name = "user-range-key-index"
        projection = AllProjection()

    user_range_key = UnicodeAttribute(hash_key=True)
```

## Valid syntax in 5.2.0

```
class UserRangeKey(GlobalSecondaryIndex):
    class Meta:
        index_name = "user-range-key-index"
        projection = AllProjection()
        billing_mode = "PAY_PER_REQUEST"

    user_range_key = UnicodeAttribute(hash_key=True)
```

Lines it breaks in is in PR [#996](https://github.com/pynamodb/PynamoDB/pull/996/commits/9fbcae919f76cbb3884f5468ec3ebcdf61148749#diff-192353ecf550dccd373608dd09309f29240c4a39a658cb67c2b5ddafbbd9ff1cR197)
Exception message is always `None`
@ikonst, I made a PR some time ago which fixes this: #1113. Is there a timeline of when we can expect it to be released?

Discussion:
ikonst: FYI @pauliokas

Patch:
diff --git a/docs/release_notes.rst b/docs/release_notes.rst
index c95e3fa..933205c 100644
--- a/docs/release_notes.rst
+++ b/docs/release_notes.rst
@@ -3,6 +3,15 @@
 Release Notes
 =============
 
+v5.3.5
+----------
+* Fix message of some exceptions derived from :class:`~pynamodb.exceptions.PynamoDBException` (#1113).
+
+Contributors to this release:
+
+* @pauliokas
+
+
 v5.3.4
 ----------
 * Make serialization :code:`null_check=False` propagate to maps inside lists (#1128).
diff --git a/pynamodb/__init__.py b/pynamodb/__init__.py
index 6828147..bd322e8 100644
--- a/pynamodb/__init__.py
+++ b/pynamodb/__init__.py
@@ -7,4 +7,4 @@ A simple abstraction over DynamoDB
 """
 __author__ = 'Jharrod LaFon'
 __license__ = 'MIT'
-__version__ = '5.3.4'
+__version__ = '5.3.5'
diff --git a/pynamodb/exceptions.py b/pynamodb/exceptions.py
index 6a7190c..7c07438 100644
--- a/pynamodb/exceptions.py
+++ b/pynamodb/exceptions.py
@@ -8,11 +8,13 @@ import botocore.exceptions
 
 
 class PynamoDBException(Exception):
+    msg: str
+
     """
     A common exception class
     """
     def __init__(self, msg: Optional[str] = None, cause: Optional[Exception] = None) -> None:
-        self.msg = msg
+        self.msg = msg if msg is not None else self.msg
         self.cause = cause
         super(PynamoDBException, self).__init__(self.msg)
 


Test patch:
diff --git a/tests/test_exceptions.py b/tests/test_exceptions.py
index 48698f1..2d70899 100644
--- a/tests/test_exceptions.py
+++ b/tests/test_exceptions.py
@@ -1,6 +1,6 @@
 from botocore.exceptions import ClientError
 
-from pynamodb.exceptions import PutError
+from pynamodb.exceptions import PynamoDBException, PutError
 
 
 def test_get_cause_response_code():
@@ -40,3 +40,10 @@ def test_get_cause_response_message__no_message():
     error = PutError()
     assert error.cause_response_message is None
 
+
+class PynamoDBTestError(PynamoDBException):
+    msg = "Test message"
+
+
+def test_subclass_message_is_not_overwritten_with_none():
+    assert PynamoDBTestError().msg == "Test message"