Skip to content

Commit 0562c63

Browse files
committed
chg: Initial changes to use new annotations
1 parent ac0421a commit 0562c63

38 files changed

+731
-723
lines changed

mypy.ini

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
[mypy]
2-
ignore_errors = False
3-
2+
strict = True
3+
warn_return_any = False
44
show_error_context = True
55
pretty = True
6-
exclude = pymisp/data|example|docs
6+
exclude = feed-generator|examples
7+
8+
# Stuff to remove gradually
9+
disallow_untyped_defs = False
10+
disallow_untyped_calls = False
11+
check_untyped_defs = False
12+
disable_error_code = attr-defined,type-arg,no-untyped-def
13+
14+
15+
[mypy-docs.source.*]
16+
ignore_errors = True

pymisp/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import annotations
2+
13
import logging
24
import sys
35
import warnings
@@ -59,4 +61,4 @@ def warning_2024():
5961
pass
6062
logger.debug('pymisp loaded properly')
6163
except ImportError as e:
62-
logger.warning('Unable to load pymisp properly: {}'.format(e))
64+
logger.warning(f'Unable to load pymisp properly: {e}')

pymisp/abstract.py

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
#!/usr/bin/env python3
2+
3+
from __future__ import annotations
4+
25
import logging
36
from datetime import date, datetime
47
from deprecated import deprecated # type: ignore
58
from json import JSONEncoder
69
from uuid import UUID
710
from abc import ABCMeta
811
from enum import Enum
9-
from typing import Union, Optional, Any, Dict, List, Set, Mapping
12+
from typing import Any, Mapping
1013
from collections.abc import MutableMapping
1114
from functools import lru_cache
1215
from pathlib import Path
1316

1417
try:
1518
import orjson # type: ignore
16-
from orjson import loads, dumps # type: ignore
19+
from orjson import loads, dumps
1720
HAS_ORJSON = True
1821
except ImportError:
1922
from json import loads, dumps
@@ -30,12 +33,12 @@
3033
describe_types = loads(f.read())['result']
3134

3235

33-
class MISPFileCache(object):
36+
class MISPFileCache:
3437
# cache up to 150 JSON structures in class attribute
3538

3639
@staticmethod
3740
@lru_cache(maxsize=150)
38-
def _load_json(path: Path) -> Optional[dict]:
41+
def _load_json(path: Path) -> dict | None:
3942
if not path.exists():
4043
return None
4144
with path.open('rb') as f:
@@ -65,7 +68,7 @@ class Analysis(Enum):
6568
completed = 2
6669

6770

68-
def _int_to_str(d: Dict[str, Any]) -> Dict[str, Any]:
71+
def _int_to_str(d: dict[str, Any]) -> dict[str, Any]:
6972
# transform all integer back to string
7073
for k, v in d.items():
7174
if isinstance(v, dict):
@@ -94,7 +97,7 @@ class AbstractMISP(MutableMapping, MISPFileCache, metaclass=ABCMeta):
9497
__misp_objects_path = misp_objects_path
9598
__describe_types = describe_types
9699

97-
def __init__(self, **kwargs: Dict):
100+
def __init__(self, **kwargs: dict):
98101
"""Abstract class for all the MISP objects.
99102
NOTE: Every method in every classes inheriting this one are doing
100103
changes in memory and do not modify data on a remote MISP instance.
@@ -103,9 +106,9 @@ def __init__(self, **kwargs: Dict):
103106
"""
104107
super().__init__()
105108
self.__edited: bool = True # As we create a new object, we assume it is edited
106-
self.__not_jsonable: List[str] = []
107-
self._fields_for_feed: Set
108-
self.__self_defined_describe_types: Optional[Dict] = None
109+
self.__not_jsonable: list[str] = []
110+
self._fields_for_feed: set
111+
self.__self_defined_describe_types: dict | None = None
109112
self.uuid: str
110113

111114
if kwargs.get('force_timestamps') is not None:
@@ -115,13 +118,13 @@ def __init__(self, **kwargs: Dict):
115118
self.__force_timestamps = False
116119

117120
@property
118-
def describe_types(self) -> Dict:
121+
def describe_types(self) -> dict:
119122
if self.__self_defined_describe_types:
120123
return self.__self_defined_describe_types
121124
return self.__describe_types
122125

123126
@describe_types.setter
124-
def describe_types(self, describe_types: Dict):
127+
def describe_types(self, describe_types: dict):
125128
self.__self_defined_describe_types = describe_types
126129

127130
@property
@@ -133,7 +136,7 @@ def misp_objects_path(self) -> Path:
133136
return self.__misp_objects_path
134137

135138
@misp_objects_path.setter
136-
def misp_objects_path(self, misp_objects_path: Union[str, Path]):
139+
def misp_objects_path(self, misp_objects_path: str | Path):
137140
if isinstance(misp_objects_path, str):
138141
misp_objects_path = Path(misp_objects_path)
139142
self.__misp_objects_path = misp_objects_path
@@ -155,7 +158,7 @@ def update_not_jsonable(self, *args) -> None:
155158
"""Add entries to the __not_jsonable list"""
156159
self.__not_jsonable += args
157160

158-
def set_not_jsonable(self, args: List[str]) -> None:
161+
def set_not_jsonable(self, args: list[str]) -> None:
159162
"""Set __not_jsonable to a new list"""
160163
self.__not_jsonable = args
161164

@@ -171,7 +174,7 @@ def from_json(self, json_string: str) -> None:
171174
"""Load a JSON string"""
172175
self.from_dict(**loads(json_string))
173176

174-
def to_dict(self, json_format: bool = False) -> Dict:
177+
def to_dict(self, json_format: bool = False) -> dict:
175178
"""Dump the class to a dictionary.
176179
This method automatically removes the timestamp recursively in every object
177180
that has been edited is order to let MISP update the event accordingly."""
@@ -213,15 +216,15 @@ def to_dict(self, json_format: bool = False) -> Dict:
213216
to_return = _int_to_str(to_return)
214217
return to_return
215218

216-
def jsonable(self) -> Dict:
219+
def jsonable(self) -> dict:
217220
"""This method is used by the JSON encoder"""
218221
return self.to_dict()
219222

220-
def _to_feed(self) -> Dict:
223+
def _to_feed(self) -> dict:
221224
if not hasattr(self, '_fields_for_feed') or not self._fields_for_feed:
222225
raise PyMISPError('Unable to export in the feed format, _fields_for_feed is missing.')
223-
if hasattr(self, '_set_default') and callable(self._set_default): # type: ignore
224-
self._set_default() # type: ignore
226+
if hasattr(self, '_set_default') and callable(self._set_default):
227+
self._set_default()
225228
to_return = {}
226229
for field in sorted(self._fields_for_feed):
227230
if getattr(self, field, None) is not None:
@@ -235,11 +238,11 @@ def _to_feed(self) -> Dict:
235238
if field in ['data', 'first_seen', 'last_seen', 'deleted']:
236239
# special fields
237240
continue
238-
raise PyMISPError('The field {} is required in {} when generating a feed.'.format(field, self.__class__.__name__))
241+
raise PyMISPError(f'The field {field} is required in {self.__class__.__name__} when generating a feed.')
239242
to_return = _int_to_str(to_return)
240243
return to_return
241244

242-
def to_json(self, sort_keys: bool = False, indent: Optional[int] = None) -> str:
245+
def to_json(self, sort_keys: bool = False, indent: int | None = None) -> str:
243246
"""Dump recursively any class of type MISPAbstract to a json string"""
244247
if HAS_ORJSON:
245248
option = 0
@@ -320,14 +323,14 @@ def __setattr__(self, name: str, value: Any):
320323
self.__edited = True
321324
super().__setattr__(name, value)
322325

323-
def _datetime_to_timestamp(self, d: Union[int, float, str, datetime]) -> int:
326+
def _datetime_to_timestamp(self, d: int | float | str | datetime) -> int:
324327
"""Convert a datetime object to a timestamp (int)"""
325328
if isinstance(d, (int, float, str)):
326329
# Assume we already have a timestamp
327330
return int(d)
328331
return int(d.timestamp())
329332

330-
def _add_tag(self, tag: Optional[Union[str, 'MISPTag', Mapping]] = None, **kwargs):
333+
def _add_tag(self, tag: str | MISPTag | Mapping | None = None, **kwargs):
331334
"""Add a tag to the attribute (by name or a MISPTag object)"""
332335
if isinstance(tag, str):
333336
misp_tag = MISPTag()
@@ -347,7 +350,7 @@ def _add_tag(self, tag: Optional[Union[str, 'MISPTag', Mapping]] = None, **kwarg
347350
self.edited = True
348351
return misp_tag
349352

350-
def _set_tags(self, tags: List['MISPTag']):
353+
def _set_tags(self, tags: list[MISPTag]):
351354
"""Set a list of prepared MISPTag."""
352355
if all(isinstance(x, MISPTag) for x in tags):
353356
self.Tag = tags
@@ -363,19 +366,19 @@ def __eq__(self, other) -> bool:
363366
return False
364367

365368
def __repr__(self) -> str:
366-
return '<{self.__class__.__name__} - please define me>'.format(self=self)
369+
return f'<{self.__class__.__name__} - please define me>'
367370

368371

369372
class MISPTag(AbstractMISP):
370373

371374
_fields_for_feed: set = {'name', 'colour', 'relationship_type', 'local'}
372375

373-
def __init__(self, **kwargs: Dict):
376+
def __init__(self, **kwargs: dict):
374377
super().__init__(**kwargs)
375378
self.name: str
376379
self.exportable: bool
377380
self.local: bool
378-
self.relationship_type: Optional[str]
381+
self.relationship_type: str | None
379382

380383
def from_dict(self, **kwargs):
381384
if kwargs.get('Tag'):
@@ -390,7 +393,7 @@ def _set_default(self):
390393
if not hasattr(self, 'local'):
391394
self.local = False
392395

393-
def _to_feed(self, with_local: bool = True) -> Dict:
396+
def _to_feed(self, with_local: bool = True) -> dict:
394397
if hasattr(self, 'exportable') and not self.exportable:
395398
return {}
396399
if with_local is False and hasattr(self, 'local') and self.local:
@@ -404,11 +407,11 @@ def delete(self):
404407
def __repr__(self) -> str:
405408
if hasattr(self, 'name'):
406409
return '<{self.__class__.__name__}(name={self.name})>'.format(self=self)
407-
return '<{self.__class__.__name__}(NotInitialized)>'.format(self=self)
410+
return f'<{self.__class__.__name__}(NotInitialized)>'
408411

409412

410413
# UUID, datetime, date and Enum is serialized by ORJSON by default
411-
def pymisp_json_default(obj: Union[AbstractMISP, datetime, date, Enum, UUID]) -> Union[Dict, str]:
414+
def pymisp_json_default(obj: AbstractMISP | datetime | date | Enum | UUID) -> dict | str:
412415
if isinstance(obj, AbstractMISP):
413416
return obj.jsonable()
414417
elif isinstance(obj, (datetime, date)):

0 commit comments

Comments
 (0)