dimp 2.4.0__tar.gz → 2.4.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. {dimp-2.4.0 → dimp-2.4.2}/PKG-INFO +19 -7
  2. {dimp-2.4.0 → dimp-2.4.2}/README.md +18 -6
  3. {dimp-2.4.0 → dimp-2.4.2}/dimp/dkd/base.py +1 -1
  4. {dimp-2.4.0 → dimp-2.4.2}/dimp/dkd/envelope.py +2 -2
  5. {dimp-2.4.0 → dimp-2.4.2}/dimp/dkd/instant.py +3 -3
  6. {dimp-2.4.0 → dimp-2.4.2}/dimp/dkd/reliable.py +3 -3
  7. {dimp-2.4.0 → dimp-2.4.2}/dimp/dkd/secure.py +3 -4
  8. {dimp-2.4.0 → dimp-2.4.2}/dimp/format/base.py +6 -2
  9. {dimp-2.4.0 → dimp-2.4.2}/dimp/format/data.py +4 -4
  10. {dimp-2.4.0 → dimp-2.4.2}/dimp/format/duri.py +12 -12
  11. {dimp-2.4.0 → dimp-2.4.2}/dimp/format/embed.py +3 -4
  12. {dimp-2.4.0 → dimp-2.4.2}/dimp/format/file.py +72 -21
  13. {dimp-2.4.0 → dimp-2.4.2}/dimp/format/file_wrapper.py +48 -15
  14. {dimp-2.4.0 → dimp-2.4.2}/dimp/mkm/docs.py +4 -4
  15. {dimp-2.4.0 → dimp-2.4.2}/dimp/mkm/document.py +12 -12
  16. {dimp-2.4.0 → dimp-2.4.2}/dimp/mkm/meta.py +9 -7
  17. {dimp-2.4.0 → dimp-2.4.2}/dimp/protocol/assets.py +30 -9
  18. {dimp-2.4.0 → dimp-2.4.2}/dimp/protocol/base.py +41 -13
  19. {dimp-2.4.0 → dimp-2.4.2}/dimp/protocol/commands.py +19 -8
  20. {dimp-2.4.0 → dimp-2.4.2}/dimp/protocol/contents.py +60 -18
  21. {dimp-2.4.0 → dimp-2.4.2}/dimp/protocol/docs.py +27 -9
  22. {dimp-2.4.0 → dimp-2.4.2}/dimp/protocol/files.py +61 -21
  23. {dimp-2.4.0 → dimp-2.4.2}/dimp/protocol/forward.py +22 -10
  24. {dimp-2.4.0 → dimp-2.4.2}/dimp/protocol/groups.py +8 -2
  25. {dimp-2.4.0 → dimp-2.4.2}/dimp/protocol/quote.py +30 -10
  26. {dimp-2.4.0 → dimp-2.4.2}/dimp/protocol/receipt.py +19 -8
  27. {dimp-2.4.0 → dimp-2.4.2}/dimp.egg-info/PKG-INFO +19 -7
  28. dimp-2.4.2/dimp.egg-info/requires.txt +2 -0
  29. {dimp-2.4.0 → dimp-2.4.2}/setup.py +3 -3
  30. dimp-2.4.0/dimp.egg-info/requires.txt +0 -2
  31. {dimp-2.4.0 → dimp-2.4.2}/LICENSE +0 -0
  32. {dimp-2.4.0 → dimp-2.4.2}/dimp/__init__.py +0 -0
  33. {dimp-2.4.0 → dimp-2.4.2}/dimp/crypto/__init__.py +0 -0
  34. {dimp-2.4.0 → dimp-2.4.2}/dimp/crypto/algorithms.py +0 -0
  35. {dimp-2.4.0 → dimp-2.4.2}/dimp/dkd/__init__.py +0 -0
  36. {dimp-2.4.0 → dimp-2.4.2}/dimp/ext/__init__.py +0 -0
  37. {dimp-2.4.0 → dimp-2.4.2}/dimp/format/__init__.py +0 -0
  38. {dimp-2.4.0 → dimp-2.4.2}/dimp/format/pnf.py +0 -0
  39. {dimp-2.4.0 → dimp-2.4.2}/dimp/format/pnf_wrapper.py +0 -0
  40. {dimp-2.4.0 → dimp-2.4.2}/dimp/mkm/__init__.py +0 -0
  41. {dimp-2.4.0 → dimp-2.4.2}/dimp/protocol/__init__.py +0 -0
  42. {dimp-2.4.0 → dimp-2.4.2}/dimp/protocol/types.py +0 -0
  43. {dimp-2.4.0 → dimp-2.4.2}/dimp/protocol/version.py +0 -0
  44. {dimp-2.4.0 → dimp-2.4.2}/dimp.egg-info/SOURCES.txt +0 -0
  45. {dimp-2.4.0 → dimp-2.4.2}/dimp.egg-info/dependency_links.txt +0 -0
  46. {dimp-2.4.0 → dimp-2.4.2}/dimp.egg-info/top_level.txt +0 -0
  47. {dimp-2.4.0 → dimp-2.4.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dimp
3
- Version: 2.4.0
3
+ Version: 2.4.2
4
4
  Summary: Decentralized Instant Messaging Protocol
5
5
  Home-page: https://github.com/dimchat/core-py
6
6
  Author: Albert Moky
@@ -91,17 +91,23 @@ class HandshakeCommand(Command, ABC):
91
91
  @property
92
92
  @abstractmethod
93
93
  def title(self) -> str:
94
- raise NotImplemented
94
+ raise NotImplementedError(
95
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.title getter'
96
+ )
95
97
 
96
98
  @property
97
99
  @abstractmethod
98
100
  def session(self) -> Optional[str]:
99
- raise NotImplemented
101
+ raise NotImplementedError(
102
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.session getter'
103
+ )
100
104
 
101
105
  @property
102
106
  @abstractmethod
103
107
  def state(self) -> HandshakeState:
104
- raise NotImplemented
108
+ raise NotImplementedError(
109
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.state getter'
110
+ )
105
111
 
106
112
  #
107
113
  # Factories
@@ -198,7 +204,9 @@ class AppContent(Content, ABC):
198
204
  @abstractmethod
199
205
  def application(self) -> str:
200
206
  """ App ID """
201
- raise NotImplemented
207
+ raise NotImplementedError(
208
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.application getter'
209
+ )
202
210
 
203
211
 
204
212
  class CustomizedContent(Content, ABC):
@@ -221,13 +229,17 @@ class CustomizedContent(Content, ABC):
221
229
  @abstractmethod
222
230
  def module(self) -> str:
223
231
  """ Module Name """
224
- raise NotImplemented
232
+ raise NotImplementedError(
233
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.module getter'
234
+ )
225
235
 
226
236
  @property
227
237
  @abstractmethod
228
238
  def action(self) -> str:
229
239
  """ Action Name """
230
- raise NotImplemented
240
+ raise NotImplementedError(
241
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.action getter'
242
+ )
231
243
 
232
244
  #
233
245
  # Factory method
@@ -77,17 +77,23 @@ class HandshakeCommand(Command, ABC):
77
77
  @property
78
78
  @abstractmethod
79
79
  def title(self) -> str:
80
- raise NotImplemented
80
+ raise NotImplementedError(
81
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.title getter'
82
+ )
81
83
 
82
84
  @property
83
85
  @abstractmethod
84
86
  def session(self) -> Optional[str]:
85
- raise NotImplemented
87
+ raise NotImplementedError(
88
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.session getter'
89
+ )
86
90
 
87
91
  @property
88
92
  @abstractmethod
89
93
  def state(self) -> HandshakeState:
90
- raise NotImplemented
94
+ raise NotImplementedError(
95
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.state getter'
96
+ )
91
97
 
92
98
  #
93
99
  # Factories
@@ -184,7 +190,9 @@ class AppContent(Content, ABC):
184
190
  @abstractmethod
185
191
  def application(self) -> str:
186
192
  """ App ID """
187
- raise NotImplemented
193
+ raise NotImplementedError(
194
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.application getter'
195
+ )
188
196
 
189
197
 
190
198
  class CustomizedContent(Content, ABC):
@@ -207,13 +215,17 @@ class CustomizedContent(Content, ABC):
207
215
  @abstractmethod
208
216
  def module(self) -> str:
209
217
  """ Module Name """
210
- raise NotImplemented
218
+ raise NotImplementedError(
219
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.module getter'
220
+ )
211
221
 
212
222
  @property
213
223
  @abstractmethod
214
224
  def action(self) -> str:
215
225
  """ Action Name """
216
- raise NotImplemented
226
+ raise NotImplementedError(
227
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.action getter'
228
+ )
217
229
 
218
230
  #
219
231
  # Factory method
@@ -67,7 +67,7 @@ class BaseMessage(Dictionary, Message):
67
67
  msg = head.to_dict()
68
68
  else:
69
69
  # 2. message info from network
70
- assert head is None, 'params error: %s, %s' % (msg, head)
70
+ assert head is None, f'params error: {msg}, {head}'
71
71
  super().__init__(dictionary=msg)
72
72
  # lazy
73
73
  self.__envelope = head
@@ -56,7 +56,7 @@ class MessageEnvelope(Dictionary, Envelope):
56
56
  sender: ID = None, receiver: Optional[ID] = None, time: Optional[DateTime] = None):
57
57
  if envelope is None:
58
58
  # 1. new envelope with sender, receiver & time
59
- assert sender is not None, 'envelope error: %s, %s' % (receiver, time)
59
+ assert sender is not None, f'envelope error: {receiver}, {time}'
60
60
  if receiver is None:
61
61
  receiver = ANYONE
62
62
  if time is None:
@@ -69,7 +69,7 @@ class MessageEnvelope(Dictionary, Envelope):
69
69
  else:
70
70
  # 2. envelope info from network
71
71
  assert sender is None and receiver is None and time is None, \
72
- 'params error: %s, %s, %s, %s' % (envelope, sender, receiver, time)
72
+ f'params error: {envelope}, {sender}, {receiver}, {time}'
73
73
  # initialize with envelope info
74
74
  super().__init__(dictionary=envelope)
75
75
  # lazy load
@@ -61,12 +61,12 @@ class PlainMessage(BaseMessage, InstantMessage):
61
61
  head: Envelope = None, body: Content = None):
62
62
  if msg is None:
63
63
  # 1. new instant message with envelope & content
64
- assert head is not None and body is not None, 'instant message error: %s, %s' % (head, body)
64
+ assert head is not None and body is not None, f'instant message error: {head}, {body}'
65
65
  super().__init__(None, head)
66
66
  # self['content'] = body.to_dict()
67
67
  else:
68
68
  # 2. message info from network
69
- assert head is None and body is None, 'params error: %s, %s, %s' % (msg, head, body)
69
+ assert head is None and body is None, f'params error: {msg}, {head}, {body}'
70
70
  super().__init__(msg, head)
71
71
  # lazy
72
72
  self.__content = body
@@ -93,7 +93,7 @@ class PlainMessage(BaseMessage, InstantMessage):
93
93
  if body is None:
94
94
  info = self.get('content')
95
95
  body = Content.parse(content=info)
96
- assert body is not None, 'message content error: %s' % self.to_dict()
96
+ assert body is not None, f'message content error: {self.to_dict()}'
97
97
  self.__content = body
98
98
  return body
99
99
 
@@ -72,9 +72,9 @@ class NetworkMessage(EncryptedMessage, ReliableMessage):
72
72
  ted = self.__signature
73
73
  if ted is None:
74
74
  base64 = self.get('signature')
75
- assert base64 is not None, 'message signature cannot be empty: %s' % self
75
+ assert base64 is not None, f'message signature cannot be empty: {self}'
76
76
  ted = TransportableData.parse(base64)
77
- assert ted is not None, 'failed to decode message signature: %s' % base64
77
+ assert ted is not None, f'failed to decode message signature: {base64}'
78
78
  self.__signature = ted
79
- assert ted is not None, 'message signature error: %s' % self.get('signature')
79
+ assert ted is not None, f'message signature error: {self.get("signature")}'
80
80
  return ted
@@ -83,9 +83,9 @@ class EncryptedMessage(BaseMessage, SecureMessage):
83
83
  # so return the string data directly
84
84
  ted = PlainData.create(string=text) # JsON
85
85
  else:
86
- assert False, 'content data error: %s' % text
86
+ assert False, f'content data error: {text}'
87
87
  self.__data = ted
88
- assert ted is not None, 'message data error: %s' % self.get('data')
88
+ assert ted is not None, f'message data error: {self.get("data")}'
89
89
  return ted
90
90
 
91
91
  @property # Override
@@ -96,6 +96,5 @@ class EncryptedMessage(BaseMessage, SecureMessage):
96
96
  if isinstance(keys, Dict):
97
97
  self.__keys = keys
98
98
  else:
99
- assert keys is None, 'message keys error: %s' % keys
100
- # TODO: get from 'key'
99
+ assert keys is None, f'message keys error: {keys}'
101
100
  return keys
@@ -101,7 +101,8 @@ class BaseString(Stringer):
101
101
  def __repr__(self) -> str:
102
102
  """ Return repr(self). """
103
103
  clazz = self.__class__.__name__
104
- return '<%s>%s</%s>' % (clazz, self.to_str(), clazz)
104
+ text = self.to_str()
105
+ return f'<{clazz}>{text}</{clazz}>'
105
106
 
106
107
 
107
108
  class BaseData(BaseString, TransportableData, ABC):
@@ -118,7 +119,10 @@ class BaseData(BaseString, TransportableData, ABC):
118
119
  # Override
119
120
  @abstractmethod
120
121
  def to_str(self) -> str:
121
- raise NotImplemented
122
+ """ Convert to string """
123
+ raise NotImplementedError(
124
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.to_str()'
125
+ )
122
126
 
123
127
  @property
124
128
  def is_empty(self) -> bool:
@@ -44,7 +44,7 @@ class Base64Data(BaseData):
44
44
  data = self._binary
45
45
  if data is None:
46
46
  base64 = self._string
47
- assert base64 is not None, 'Base64Data error: %s' % self
47
+ assert base64 is not None, f'Base64Data error: {self}'
48
48
  data = base64_decode(string=base64)
49
49
  self._binary = data
50
50
  return data
@@ -54,7 +54,7 @@ class Base64Data(BaseData):
54
54
  base64 = self._string
55
55
  if base64 is None or len(base64) == 0:
56
56
  data = self._binary
57
- assert data is not None, 'Base64Data error: %s' % self
57
+ assert data is not None, f'Base64Data error: {self}'
58
58
  base64 = base64_encode(data=data)
59
59
  self._string = base64
60
60
  return base64
@@ -82,7 +82,7 @@ class PlainData(BaseData):
82
82
  data = self._binary
83
83
  if data is None:
84
84
  txt = self._string
85
- assert txt is not None, 'PlainData error: %s' % self
85
+ assert txt is not None, f'PlainData error: {self}'
86
86
  data = utf8_encode(string=txt)
87
87
  self._binary = data
88
88
  return data
@@ -92,7 +92,7 @@ class PlainData(BaseData):
92
92
  txt = self._string
93
93
  if txt is None or len(txt) == 0:
94
94
  data = self._binary
95
- assert data is not None, 'PlainData error: %s' % self
95
+ assert data is not None, f'PlainData error: {self}'
96
96
  txt = utf8_decode(data=data)
97
97
  self._string = txt
98
98
  return txt
@@ -110,9 +110,9 @@ class Header:
110
110
  # 2. extra info: 'charset' & 'filename'
111
111
  #
112
112
  if extra is not None:
113
- for key in extra:
114
- value = extra[key]
115
- pair = '%s=%s' % (key, value)
113
+ for key, value in extra.items():
114
+ # TODO: encode(value)
115
+ pair = f'{key}={value}'
116
116
  items.append(pair)
117
117
  #
118
118
  # 3. 'encoding'
@@ -139,7 +139,7 @@ class Header:
139
139
  if end < 6:
140
140
  # header empty
141
141
  return Header(mime_type='')
142
- assert end < len(uri) - 1, 'data URI error: %s' % uri
142
+ assert end < len(uri) - 1, f'data URI error: {uri}'
143
143
  array = uri[5:end].split(';')
144
144
  # split main info
145
145
  mime_type: str = None
@@ -148,14 +148,14 @@ class Header:
148
148
  extra: Dict[str, str] = None
149
149
  for item in array:
150
150
  if len(item) == 0:
151
- # assert False, 'header error: %s' % uri
151
+ # assert False, f'header error: {uri}'
152
152
  continue
153
153
  #
154
154
  # 2. extra info: 'charset' or 'filename'
155
155
  #
156
156
  pos = item.find('=')
157
157
  if pos >= 0:
158
- assert 0 < pos < len(item) - 1, 'header error: %s' % item
158
+ assert 0 < pos < len(item) - 1, f'header error: {item}'
159
159
  if extra is None:
160
160
  extra = {}
161
161
  name = item[:pos].lower()
@@ -167,14 +167,14 @@ class Header:
167
167
  #
168
168
  pos = item.find('/')
169
169
  if pos >= 0:
170
- assert 0 < pos < len(item) - 1, 'header error: %s' % item
171
- assert mime_type is None, 'duplicate mime-type: %s' % uri
170
+ assert 0 < pos < len(item) - 1, f'header error: {item}'
171
+ assert mime_type is None, f'duplicate mime-type: {uri}'
172
172
  mime_type = item
173
173
  continue
174
174
  #
175
175
  # 3. 'encoding'
176
176
  #
177
- assert encoding is None, 'duplicate encoding: %s' % uri
177
+ assert encoding is None, f'duplicate encoding: {uri}'
178
178
  encoding = item
179
179
  # OK
180
180
  if mime_type is None:
@@ -258,9 +258,9 @@ class DataURI:
258
258
  if text is None:
259
259
  header = self.head.to_str()
260
260
  if len(header) == 0:
261
- text = 'data:,%s' % self.body
261
+ text = f'data:,{self.body}'
262
262
  else:
263
- text = 'data:%s,%s' % (header, self.body)
263
+ text = f'data:{header},{self.body}'
264
264
  self.__uri_string = text
265
265
  return text
266
266
 
@@ -277,7 +277,7 @@ class DataURI:
277
277
  return None
278
278
  pos = uri.find(',')
279
279
  if pos < 0:
280
- # assert False, 'data URI error: %s' % uri
280
+ # assert False, f'data URI error: {uri}'
281
281
  return None
282
282
  head = Header.split_header(uri=uri, end=pos)
283
283
  body = uri[pos+1:]
@@ -156,10 +156,9 @@ class EmbedData(BaseData):
156
156
  header = 'text/plain' if mime_type is None else mime_type
157
157
  extra = self.__parameters
158
158
  if extra is not None:
159
- for key in extra:
160
- value = extra[key]
161
- header += ';%s=%s' % (key, value)
162
- txt = 'data:%s;base64,%s' % (header, body)
159
+ for key, value in extra.items():
160
+ header += f';{key}={value}'
161
+ txt = f'data:{header};base64,{body}'
163
162
  # self._string = txt
164
163
  # parse for data URI
165
164
  uri = DataURI.parse(uri=txt)
@@ -63,22 +63,34 @@ class TransportableFile(Mapper, TransportableResource, ABC):
63
63
  @property
64
64
  @abstractmethod
65
65
  def data(self) -> Optional[TransportableData]:
66
- raise NotImplemented
66
+ """ Get file data """
67
+ raise NotImplementedError(
68
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.data getter'
69
+ )
67
70
 
68
71
  @data.setter
69
72
  @abstractmethod
70
73
  def data(self, content: Optional[TransportableData]):
71
- raise NotImplemented
74
+ """ Set file data """
75
+ raise NotImplementedError(
76
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.data setter'
77
+ )
72
78
 
73
79
  @property
74
80
  @abstractmethod
75
81
  def filename(self) -> Optional[str]:
76
- raise NotImplemented
82
+ """ Get filename """
83
+ raise NotImplementedError(
84
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.filename getter'
85
+ )
77
86
 
78
87
  @filename.setter
79
88
  @abstractmethod
80
89
  def filename(self, string: Optional[str]):
81
- raise NotImplemented
90
+ """ Set filename """
91
+ raise NotImplementedError(
92
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.filename setter'
93
+ )
82
94
 
83
95
  #
84
96
  # Download URL
@@ -86,13 +98,18 @@ class TransportableFile(Mapper, TransportableResource, ABC):
86
98
  @property
87
99
  @abstractmethod
88
100
  def url(self) -> Optional[URI]:
89
- # download URL from CDN
90
- raise NotImplemented
101
+ """ Get download URL from CDN """
102
+ raise NotImplementedError(
103
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.url getter'
104
+ )
91
105
 
92
106
  @url.setter
93
107
  @abstractmethod
94
108
  def url(self, string: Optional[URI]):
95
- raise NotImplemented
109
+ """ Set URL """
110
+ raise NotImplementedError(
111
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.url setter'
112
+ )
96
113
 
97
114
  #
98
115
  # Password for decrypting the downloaded data from CDN,
@@ -101,12 +118,18 @@ class TransportableFile(Mapper, TransportableResource, ABC):
101
118
  @property
102
119
  @abstractmethod
103
120
  def password(self) -> Optional[DecryptKey]:
104
- raise NotImplemented
121
+ """ Get password """
122
+ raise NotImplementedError(
123
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.password getter'
124
+ )
105
125
 
106
126
  @password.setter
107
127
  @abstractmethod
108
128
  def password(self, key: Optional[DecryptKey]):
109
- raise NotImplemented
129
+ """ Set password """
130
+ raise NotImplementedError(
131
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.password setter'
132
+ )
110
133
 
111
134
  # Override
112
135
  @abstractmethod
@@ -116,13 +139,17 @@ class TransportableFile(Mapper, TransportableResource, ABC):
116
139
 
117
140
  :return: 'URL', or JSON string: '{...}'
118
141
  """
119
- raise NotImplemented
142
+ raise NotImplementedError(
143
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.__str__()'
144
+ )
120
145
 
121
146
  # Override
122
147
  @abstractmethod
123
148
  def to_dict(self) -> Dict:
124
- """ serialize to map """
125
- raise NotImplemented
149
+ """ Serialize to map """
150
+ raise NotImplementedError(
151
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.to_dict()'
152
+ )
126
153
 
127
154
  # Override
128
155
  @abstractmethod
@@ -132,7 +159,9 @@ class TransportableFile(Mapper, TransportableResource, ABC):
132
159
 
133
160
  :return: str or dict
134
161
  """
135
- return NotImplemented
162
+ raise NotImplementedError(
163
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.serialize()'
164
+ )
136
165
 
137
166
  #
138
167
  # Factory methods
@@ -183,7 +212,9 @@ class TransportableFileFactory(ABC):
183
212
  :param password: decrypt key for downloaded data
184
213
  :return: PNF object
185
214
  """
186
- raise NotImplemented
215
+ raise NotImplementedError(
216
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.create_transportable_file()'
217
+ )
187
218
 
188
219
  @abstractmethod
189
220
  def parse_transportable_file(self, pnf: Dict) -> Optional[TransportableFile]:
@@ -193,7 +224,9 @@ class TransportableFileFactory(ABC):
193
224
  :param pnf: PNF info
194
225
  :return: PNF object
195
226
  """
196
- raise NotImplemented
227
+ raise NotImplementedError(
228
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.parse_transportable_file()'
229
+ )
197
230
 
198
231
 
199
232
  # -----------------------------------------------------------------------------
@@ -206,31 +239,49 @@ class TransportableFileHelper(ABC):
206
239
 
207
240
  @abstractmethod
208
241
  def set_transportable_file_factory(self, factory: TransportableFileFactory):
209
- raise NotImplemented
242
+ """ Set PNF factory """
243
+ raise NotImplementedError(
244
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.set_transportable_file_factory()'
245
+ )
210
246
 
211
247
  @abstractmethod
212
248
  def get_transportable_file_factory(self) -> Optional[TransportableFileFactory]:
213
- raise NotImplemented
249
+ """ Get PNF factory """
250
+ raise NotImplementedError(
251
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.get_transportable_file_factory()'
252
+ )
214
253
 
215
254
  @abstractmethod
216
255
  def create_transportable_file(self, data: Optional[TransportableData], filename: Optional[str],
217
256
  url: Optional[URI], password: Optional[DecryptKey]) -> TransportableFile:
218
- raise NotImplemented
257
+ """ Create PNF """
258
+ raise NotImplementedError(
259
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.create_transportable_file()'
260
+ )
219
261
 
220
262
  @abstractmethod
221
263
  def parse_transportable_file(self, pnf: Any) -> Optional[TransportableFile]:
222
- raise NotImplemented
264
+ """ Parse any object to PNF """
265
+ raise NotImplementedError(
266
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.parse_transportable_file()'
267
+ )
223
268
 
224
269
 
225
270
  class TransportableFileExtension:
226
271
 
227
272
  @property
228
273
  def pnf_helper(self) -> Optional[TransportableFileHelper]:
229
- raise NotImplemented
274
+ """ Get PNF helper """
275
+ raise NotImplementedError(
276
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.pnf_helper getter'
277
+ )
230
278
 
231
279
  @pnf_helper.setter
232
280
  def pnf_helper(self, helper: TransportableFileHelper):
233
- raise NotImplemented
281
+ """ Set PNF helper """
282
+ raise NotImplementedError(
283
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.pnf_helper setter'
284
+ )
234
285
 
235
286
 
236
287
  shared_format_extensions.pnf_helper: Optional[TransportableFileHelper] = None