rucio-clients 32.8.6__py3-none-any.whl → 35.8.0__py3-none-any.whl

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.

Potentially problematic release.


This version of rucio-clients might be problematic. Click here for more details.

Files changed (92) hide show
  1. rucio/__init__.py +0 -1
  2. rucio/alembicrevision.py +1 -2
  3. rucio/client/__init__.py +0 -1
  4. rucio/client/accountclient.py +45 -25
  5. rucio/client/accountlimitclient.py +37 -9
  6. rucio/client/baseclient.py +199 -154
  7. rucio/client/client.py +2 -3
  8. rucio/client/configclient.py +19 -6
  9. rucio/client/credentialclient.py +9 -4
  10. rucio/client/didclient.py +238 -63
  11. rucio/client/diracclient.py +13 -5
  12. rucio/client/downloadclient.py +162 -51
  13. rucio/client/exportclient.py +4 -4
  14. rucio/client/fileclient.py +3 -4
  15. rucio/client/importclient.py +4 -4
  16. rucio/client/lifetimeclient.py +21 -5
  17. rucio/client/lockclient.py +18 -8
  18. rucio/client/{metaclient.py → metaconventionsclient.py} +18 -15
  19. rucio/client/pingclient.py +0 -1
  20. rucio/client/replicaclient.py +15 -5
  21. rucio/client/requestclient.py +35 -19
  22. rucio/client/rseclient.py +133 -51
  23. rucio/client/ruleclient.py +29 -22
  24. rucio/client/scopeclient.py +8 -6
  25. rucio/client/subscriptionclient.py +47 -35
  26. rucio/client/touchclient.py +8 -4
  27. rucio/client/uploadclient.py +166 -82
  28. rucio/common/__init__.py +0 -1
  29. rucio/common/cache.py +4 -4
  30. rucio/common/config.py +52 -47
  31. rucio/common/constants.py +69 -2
  32. rucio/common/constraints.py +0 -1
  33. rucio/common/didtype.py +24 -22
  34. rucio/common/exception.py +281 -222
  35. rucio/common/extra.py +0 -1
  36. rucio/common/logging.py +54 -38
  37. rucio/common/pcache.py +122 -101
  38. rucio/common/plugins.py +153 -0
  39. rucio/common/policy.py +4 -4
  40. rucio/common/schema/__init__.py +17 -10
  41. rucio/common/schema/atlas.py +7 -5
  42. rucio/common/schema/belleii.py +7 -5
  43. rucio/common/schema/domatpc.py +7 -5
  44. rucio/common/schema/escape.py +7 -5
  45. rucio/common/schema/generic.py +8 -6
  46. rucio/common/schema/generic_multi_vo.py +7 -5
  47. rucio/common/schema/icecube.py +7 -5
  48. rucio/common/stomp_utils.py +0 -1
  49. rucio/common/stopwatch.py +0 -1
  50. rucio/common/test_rucio_server.py +2 -2
  51. rucio/common/types.py +262 -17
  52. rucio/common/utils.py +743 -451
  53. rucio/rse/__init__.py +3 -4
  54. rucio/rse/protocols/__init__.py +0 -1
  55. rucio/rse/protocols/bittorrent.py +184 -0
  56. rucio/rse/protocols/cache.py +1 -2
  57. rucio/rse/protocols/dummy.py +1 -2
  58. rucio/rse/protocols/gfal.py +12 -10
  59. rucio/rse/protocols/globus.py +7 -7
  60. rucio/rse/protocols/gsiftp.py +2 -3
  61. rucio/rse/protocols/http_cache.py +1 -2
  62. rucio/rse/protocols/mock.py +1 -2
  63. rucio/rse/protocols/ngarc.py +1 -2
  64. rucio/rse/protocols/posix.py +12 -13
  65. rucio/rse/protocols/protocol.py +116 -52
  66. rucio/rse/protocols/rclone.py +6 -7
  67. rucio/rse/protocols/rfio.py +4 -5
  68. rucio/rse/protocols/srm.py +9 -10
  69. rucio/rse/protocols/ssh.py +8 -9
  70. rucio/rse/protocols/storm.py +2 -3
  71. rucio/rse/protocols/webdav.py +17 -14
  72. rucio/rse/protocols/xrootd.py +23 -17
  73. rucio/rse/rsemanager.py +19 -7
  74. rucio/vcsversion.py +4 -4
  75. rucio/version.py +5 -13
  76. rucio_clients-35.8.0.data/data/requirements.client.txt +15 -0
  77. {rucio_clients-32.8.6.data → rucio_clients-35.8.0.data}/data/rucio_client/merge_rucio_configs.py +2 -5
  78. {rucio_clients-32.8.6.data → rucio_clients-35.8.0.data}/scripts/rucio +87 -85
  79. {rucio_clients-32.8.6.data → rucio_clients-35.8.0.data}/scripts/rucio-admin +45 -32
  80. {rucio_clients-32.8.6.dist-info → rucio_clients-35.8.0.dist-info}/METADATA +13 -13
  81. rucio_clients-35.8.0.dist-info/RECORD +88 -0
  82. {rucio_clients-32.8.6.dist-info → rucio_clients-35.8.0.dist-info}/WHEEL +1 -1
  83. {rucio_clients-32.8.6.dist-info → rucio_clients-35.8.0.dist-info}/licenses/AUTHORS.rst +3 -0
  84. rucio/common/schema/cms.py +0 -478
  85. rucio/common/schema/lsst.py +0 -423
  86. rucio_clients-32.8.6.data/data/requirements.txt +0 -55
  87. rucio_clients-32.8.6.dist-info/RECORD +0 -88
  88. {rucio_clients-32.8.6.data → rucio_clients-35.8.0.data}/data/etc/rse-accounts.cfg.template +0 -0
  89. {rucio_clients-32.8.6.data → rucio_clients-35.8.0.data}/data/etc/rucio.cfg.atlas.client.template +0 -0
  90. {rucio_clients-32.8.6.data → rucio_clients-35.8.0.data}/data/etc/rucio.cfg.template +0 -0
  91. {rucio_clients-32.8.6.dist-info → rucio_clients-35.8.0.dist-info}/licenses/LICENSE +0 -0
  92. {rucio_clients-32.8.6.dist-info → rucio_clients-35.8.0.dist-info}/top_level.txt +0 -0
rucio/common/config.py CHANGED
@@ -1,4 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
1
  # Copyright European Organization for Nuclear Research (CERN) since 2012
3
2
  #
4
3
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,7 +18,7 @@ import configparser
19
18
  import json
20
19
  import os
21
20
  from collections.abc import Callable
22
- from typing import TYPE_CHECKING, overload, Optional, TypeVar, Union
21
+ from typing import TYPE_CHECKING, Any, Optional, TypeVar, Union, overload
23
22
 
24
23
  from rucio.common import exception
25
24
  from rucio.common.exception import ConfigNotFound, DatabaseException
@@ -31,7 +30,7 @@ if TYPE_CHECKING:
31
30
  from sqlalchemy.orm import Session
32
31
 
33
32
 
34
- def convert_to_any_type(value) -> Union[bool, int, float, str]:
33
+ def convert_to_any_type(value: str) -> Union[bool, int, float, str]:
35
34
  if value.lower() in ['true', 'yes', 'on']:
36
35
  return True
37
36
  elif value.lower() in ['false', 'no', 'off']:
@@ -46,7 +45,7 @@ def convert_to_any_type(value) -> Union[bool, int, float, str]:
46
45
  return value
47
46
 
48
47
 
49
- def _convert_to_boolean(value):
48
+ def _convert_to_boolean(value: Union[str, bool]) -> bool:
50
49
  if isinstance(value, bool):
51
50
  return value
52
51
  if value.lower() in ['true', 'yes', 'on', '1']:
@@ -189,12 +188,12 @@ def config_get(
189
188
  """
190
189
  try:
191
190
  return convert_type_fnc(get_config().get(section, option))
192
- except (configparser.NoOptionError, configparser.NoSectionError, RuntimeError) as err:
191
+ except (configparser.NoOptionError, configparser.NoSectionError, ConfigNotFound) as err:
193
192
  try:
194
193
  legacy_config = get_legacy_config(section, option)
195
194
  if legacy_config is not None:
196
195
  return convert_type_fnc(legacy_config)
197
- except RuntimeError:
196
+ except ConfigNotFound:
198
197
  pass
199
198
 
200
199
  from rucio.common.utils import is_client
@@ -298,7 +297,7 @@ def config_get_int(
298
297
  def config_get_int(
299
298
  section: str,
300
299
  option: str,
301
- raise_exception,
300
+ raise_exception: bool,
302
301
  default: _T = ...,
303
302
  *,
304
303
  check_config_table: bool = ...,
@@ -310,14 +309,14 @@ def config_get_int(
310
309
 
311
310
 
312
311
  def config_get_int(
313
- section,
314
- option,
315
- raise_exception=True,
312
+ section: str,
313
+ option: str,
314
+ raise_exception: bool = True,
316
315
  default=None,
317
- check_config_table=True,
318
- session=None,
319
- use_cache=True,
320
- expiration_time=900,
316
+ check_config_table: bool = True,
317
+ session: "Optional[Session]" = None,
318
+ use_cache: bool = True,
319
+ expiration_time: int = 900,
321
320
  ):
322
321
  """
323
322
  Return the integer value for a given option in a section
@@ -396,14 +395,14 @@ def config_get_float(
396
395
 
397
396
 
398
397
  def config_get_float(
399
- section,
400
- option,
401
- raise_exception=True,
398
+ section: str,
399
+ option: str,
400
+ raise_exception: bool = True,
402
401
  default=None,
403
- check_config_table=True,
404
- session=None,
405
- use_cache=True,
406
- expiration_time=900,
402
+ check_config_table: bool = True,
403
+ session: "Optional[Session]" = None,
404
+ use_cache: bool = True,
405
+ expiration_time: int = 900,
407
406
  ):
408
407
  """
409
408
  Return the floating point value for a given option in a section
@@ -483,14 +482,14 @@ def config_get_bool(
483
482
 
484
483
 
485
484
  def config_get_bool(
486
- section,
487
- option,
488
- raise_exception=True,
485
+ section: str,
486
+ option: str,
487
+ raise_exception: bool = True,
489
488
  default=None,
490
- check_config_table=True,
491
- session=None,
492
- use_cache=True,
493
- expiration_time=900,
489
+ check_config_table: bool = True,
490
+ session: "Optional[Session]" = None,
491
+ use_cache: bool = True,
492
+ expiration_time: int = 900,
494
493
  ):
495
494
  """
496
495
  Return the boolean value for a given option in a section
@@ -570,14 +569,14 @@ def config_get_list(
570
569
 
571
570
 
572
571
  def config_get_list(
573
- section,
574
- option,
575
- raise_exception=True,
572
+ section: str,
573
+ option: str,
574
+ raise_exception: bool = True,
576
575
  default=None,
577
- check_config_table=True,
578
- session=None,
579
- use_cache=True,
580
- expiration_time=900,
576
+ check_config_table: bool = True,
577
+ session: "Optional[Session]" = None,
578
+ use_cache: bool = True,
579
+ expiration_time: int = 900,
581
580
  ):
582
581
  """
583
582
  Return a list for a given option in a section
@@ -692,7 +691,7 @@ def config_remove_option(section: str, option: str) -> bool:
692
691
  return get_config().remove_option(section, option)
693
692
 
694
693
 
695
- def config_set(section: str, option: str, value: str):
694
+ def config_set(section: str, option: str, value: str) -> None:
696
695
  """
697
696
  Set a configuration option in a given section.
698
697
 
@@ -705,11 +704,12 @@ def config_set(section: str, option: str, value: str):
705
704
  return get_config().set(section, option, value)
706
705
 
707
706
 
708
- def get_config_dirs():
707
+ def get_config_dirs() -> list[str]:
709
708
  """
710
709
  Returns all available configuration directories in order:
711
710
  - $RUCIO_HOME/etc/
712
711
  - $VIRTUAL_ENV/etc/
712
+ - $CONDA_PREFIX/etc
713
713
  - /opt/rucio/
714
714
  """
715
715
  configdirs = []
@@ -720,22 +720,25 @@ def get_config_dirs():
720
720
  if 'VIRTUAL_ENV' in os.environ:
721
721
  configdirs.append('%s/etc/' % os.environ['VIRTUAL_ENV'])
722
722
 
723
+ if 'CONDA_PREFIX' in os.environ:
724
+ configdirs.append('%s/etc/' % os.environ['CONDA_PREFIX'])
725
+
723
726
  configdirs.append('/opt/rucio/etc/')
724
727
 
725
728
  return configdirs
726
729
 
727
730
 
728
- def get_lfn2pfn_algorithm_default():
731
+ def get_lfn2pfn_algorithm_default() -> str:
729
732
  """Returns the default algorithm name for LFN2PFN translation for this server."""
730
733
  default_lfn2pfn = "hash"
731
734
  try:
732
735
  default_lfn2pfn = config_get('policy', 'lfn2pfn_algorithm_default')
733
- except (configparser.NoOptionError, configparser.NoSectionError, RuntimeError):
736
+ except (configparser.NoOptionError, configparser.NoSectionError, ConfigNotFound, RuntimeError):
734
737
  pass
735
738
  return default_lfn2pfn
736
739
 
737
740
 
738
- def get_rse_credentials(path_to_credentials_file: Optional[Union[str, os.PathLike]] = None):
741
+ def get_rse_credentials(path_to_credentials_file: Optional[Union[str, os.PathLike]] = None) -> dict[str, Any]:
739
742
  """ Returns credentials for RSEs. """
740
743
 
741
744
  path = ''
@@ -766,7 +769,7 @@ def get_config() -> configparser.ConfigParser:
766
769
  return __CONFIG.parser
767
770
 
768
771
 
769
- def clean_cached_config():
772
+ def clean_cached_config() -> None:
770
773
  """Deletes the cached config singleton instance."""
771
774
  global __CONFIG
772
775
  __CONFIG = None
@@ -786,11 +789,13 @@ class Config:
786
789
  configs = [os.path.join(confdir, 'rucio.cfg') for confdir in get_config_dirs()]
787
790
  self.configfile = next(iter(filter(os.path.exists, configs)), None)
788
791
  if self.configfile is None:
789
- raise RuntimeError('Could not load Rucio configuration file. '
790
- 'Rucio looked in the following paths for a configuration file, in order:'
791
- '\n\t' + '\n\t'.join(configs))
792
+ raise ConfigNotFound(
793
+ 'Could not load Rucio configuration file. '
794
+ 'Rucio looked in the following paths for a configuration file, in order:'
795
+ '\n\t' + '\n\t'.join(configs))
792
796
 
793
797
  if not self.parser.read(self.configfile) == [self.configfile]:
794
- raise RuntimeError('Could not load Rucio configuration file. '
795
- 'Rucio tried loading the following configuration file:'
796
- '\n\t' + self.configfile)
798
+ raise ConfigNotFound(
799
+ 'Could not load Rucio configuration file. '
800
+ 'Rucio tried loading the following configuration file:'
801
+ '\n\t' + self.configfile)
rucio/common/constants.py CHANGED
@@ -1,4 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
1
  # Copyright European Organization for Nuclear Research (CERN) since 2012
3
2
  #
4
3
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,6 +14,7 @@
15
14
 
16
15
  import enum
17
16
  from collections import namedtuple
17
+ from typing import Literal, get_args
18
18
 
19
19
  from rucio.common.config import config_get_bool
20
20
 
@@ -48,7 +48,16 @@ if config_get_bool('transfers', 'srm_https_compatibility', raise_exception=False
48
48
  SCHEME_MAP['srm'].append('davs')
49
49
  SCHEME_MAP['davs'].append('srm')
50
50
 
51
- SUPPORTED_PROTOCOLS = ['gsiftp', 'srm', 'root', 'davs', 'http', 'https', 'file', 'storm', 'srm+https', 'scp', 'rsync', 'rclone']
51
+ SORTING_ALGORITHMS_LITERAL = Literal['geoip', 'closeness', 'custom_table', 'dynamic', 'ranking', 'random']
52
+ SORTING_ALGORITHMS = list(get_args(SORTING_ALGORITHMS_LITERAL))
53
+
54
+ SUPPORTED_PROTOCOLS_LITERAL = Literal['gsiftp', 'srm', 'root', 'davs', 'http', 'https', 'file', 'storm', 'srm+https', 'scp', 'rsync', 'rclone', 'magnet']
55
+ SUPPORTED_PROTOCOLS: list[str] = list(get_args(SUPPORTED_PROTOCOLS_LITERAL))
56
+
57
+ RSE_SUPPORTED_PROTOCOL_DOMAINS_LITERAL = Literal['ALL', 'LAN', 'WAN']
58
+
59
+ RSE_SUPPORTED_PROTOCOL_OPERATIONS_LITERAL = Literal['read', 'write', 'delete', 'third_party_copy_read', 'third_party_copy_write']
60
+ RSE_SUPPORTED_PROTOCOL_OPERATIONS: list[str] = list(get_args(RSE_SUPPORTED_PROTOCOL_OPERATIONS_LITERAL))
52
61
 
53
62
  FTS_STATE = namedtuple('FTS_STATE', ['SUBMITTED', 'READY', 'ACTIVE', 'FAILED', 'FINISHED', 'FINISHEDDIRTY', 'NOT_USED',
54
63
  'CANCELED'])('SUBMITTED', 'READY', 'ACTIVE', 'FAILED', 'FINISHED', 'FINISHEDDIRTY',
@@ -90,3 +99,61 @@ class HermesService(str, enum.Enum):
90
99
  ELASTIC = "ELASTIC"
91
100
  EMAIL = "EMAIL"
92
101
  ACTIVEMQ = "ACTIVEMQ"
102
+
103
+
104
+ class RseAttr:
105
+
106
+ """
107
+ List of functional RSE attributes.
108
+
109
+ This class acts as a namespace containing all RSE attributes referenced in
110
+ the Rucio source code. Setting them affects Rucio's behaviour in some way.
111
+ """
112
+
113
+ ARCHIVE_TIMEOUT = 'archive_timeout'
114
+ ASSOCIATED_SITES = 'associated_sites'
115
+ AUTO_APPROVE_BYTES = 'auto_approve_bytes'
116
+ AUTO_APPROVE_FILES = 'auto_approve_files'
117
+ BITTORRENT_TRACKER_ADDR = 'bittorrent_tracker_addr'
118
+ BLOCK_MANUAL_APPROVAL = 'block_manual_approval'
119
+ COUNTRY = 'country'
120
+ DECOMMISSION = 'decommission'
121
+ DEFAULT_ACCOUNT_LIMIT_BYTES = 'default_account_limit_bytes'
122
+ FTS = 'fts'
123
+ GLOBUS_ENDPOINT_ID = 'globus_endpoint_id'
124
+ GREEDYDELETION = 'greedyDeletion'
125
+ IS_OBJECT_STORE = 'is_object_store'
126
+ LFN2PFN_ALGORITHM = 'lfn2pfn_algorithm'
127
+ MAXIMUM_PIN_LIFETIME = 'maximum_pin_lifetime'
128
+ MULTIHOP_TOMBSTONE_DELAY = 'multihop_tombstone_delay'
129
+ NAMING_CONVENTION = 'naming_convention'
130
+ OIDC_BASE_PATH = 'oidc_base_path'
131
+ OIDC_SUPPORT = 'oidc_support'
132
+ PHYSGROUP = 'physgroup'
133
+ QBITTORRENT_MANAGEMENT_ADDRESS = 'qbittorrent_management_address'
134
+ RESTRICTED_READ = 'restricted_read'
135
+ RESTRICTED_WRITE = 'restricted_write'
136
+ RULE_APPROVERS = 'rule_approvers'
137
+ S3_URL_STYLE = 's3_url_style'
138
+ SIGN_URL = 'sign_url'
139
+ SIMULATE_MULTIRANGE = 'simulate_multirange'
140
+ SITE = 'site'
141
+ SKIP_UPLOAD_STAT = 'skip_upload_stat'
142
+ SOURCE_FOR_TOTAL_SPACE = 'source_for_total_space'
143
+ SOURCE_FOR_USED_SPACE = 'source_for_used_space'
144
+ STAGING_BUFFER = 'staging_buffer'
145
+ STAGING_REQUIRED = 'staging_required'
146
+ STRICT_COPY = 'strict_copy'
147
+ TOMBSTONE_DELAY = 'tombstone_delay'
148
+ TYPE = 'type'
149
+ USE_IPV4 = 'use_ipv4'
150
+ VERIFY_CHECKSUM = 'verify_checksum'
151
+
152
+ # The following RSE attributes are exclusively used in the permission layer
153
+ # and are likely VO-specific.
154
+
155
+ BLOCK_MANUAL_APPROVE = 'block_manual_approve'
156
+ CMS_TYPE = 'cms_type'
157
+ DEFAULT_LIMIT_FILES = 'default_limit_files'
158
+ QUOTA_APPROVERS = 'quota_approvers'
159
+ RULE_DELETERS = 'rule_deleters'
@@ -1,4 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
1
  # Copyright European Organization for Nuclear Research (CERN) since 2012
3
2
  #
4
3
  # Licensed under the Apache License, Version 2.0 (the "License");
rucio/common/didtype.py CHANGED
@@ -1,4 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
1
  # Copyright European Organization for Nuclear Research (CERN) since 2012
3
2
  #
4
3
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,10 +16,12 @@
17
16
  DID type to represent a did and to simplify operations on it
18
17
  """
19
18
 
19
+ from typing import Union
20
+
20
21
  from rucio.common.exception import DIDError
21
22
 
22
23
 
23
- class DID(object):
24
+ class DID:
24
25
 
25
26
  """
26
27
  Class used to store a DID
@@ -54,29 +55,30 @@ class DID(object):
54
55
  DID('arg.scope', name='kwarg.name')
55
56
  DID('arg.name', scope='kwarg.scope')
56
57
  """
57
- self.scope = self.name = ''
58
+ self.scope: str = ''
59
+ self.name: str = ''
58
60
 
59
61
  num_args = len(args)
60
62
  num_kwargs = len(kwargs)
61
63
  if (num_args + num_kwargs) > 2:
62
64
  raise DIDError('Constructor takes at most 2 arguments. Given number: {}'.format(num_args + num_kwargs))
63
65
 
64
- did = ''
66
+ did: Union["DID", str, tuple[str, str], list[str], dict[str, str]] = ''
65
67
  if num_args == 1:
66
68
  did = args[0]
67
69
 
68
70
  if num_kwargs == 1:
69
- if not isinstance(did, str):
71
+ if isinstance(did, str):
72
+ k, v = next(iter(kwargs.items()))
73
+ if k == 'scope':
74
+ did = (v, did)
75
+ elif k == 'name':
76
+ did = (did, v)
77
+ else:
78
+ raise DIDError('Constructor got unexpected keyword argument: {}'.format(k))
79
+ else:
70
80
  raise DIDError('First argument of constructor is expected to be string type'
71
81
  'when keyword argument is given. Given type: {}'.format(type(did)))
72
-
73
- k, v = next(iter(kwargs.items()))
74
- if k == 'scope':
75
- did = (v, did)
76
- elif k == 'name':
77
- did = (did, v)
78
- else:
79
- raise DIDError('Constructor got unexpected keyword argument: {}'.format(k))
80
82
  elif num_args == 0:
81
83
  did = kwargs.get('did', kwargs)
82
84
  else:
@@ -114,16 +116,16 @@ class DID(object):
114
116
  if not self.is_valid_format():
115
117
  raise DIDError('Object has invalid format after construction: {}'.format(str(self)))
116
118
 
117
- def update_implicit_scope(self):
119
+ def update_implicit_scope(self) -> None:
118
120
  """
119
- This method sets the scope if it is implicitly given in self.name
121
+ This method sets the scope if it is implicitly given in self.name
120
122
  """
121
123
  did_parts = self.name.split(DID.IMPLICIT_SCOPE_SEPARATOR)
122
124
  num_scope_parts = DID.IMPLICIT_SCOPE_TO_LEN.get(did_parts[0], 0)
123
125
  if num_scope_parts > 0:
124
126
  self.scope = '.'.join(did_parts[0:num_scope_parts])
125
127
 
126
- def is_valid_format(self):
128
+ def is_valid_format(self) -> bool:
127
129
  """
128
130
  Method to check if the stored DID has a valid format
129
131
  :return: bool
@@ -132,21 +134,21 @@ class DID(object):
132
134
  return False
133
135
  return True
134
136
 
135
- def has_scope(self):
137
+ def has_scope(self) -> bool:
136
138
  """
137
139
  Method to check if the scope part was set
138
140
  :return: bool
139
141
  """
140
142
  return len(self.scope) > 0
141
143
 
142
- def has_name(self):
144
+ def has_name(self) -> bool:
143
145
  """
144
146
  Method to check if the name part was set
145
147
  :return: bool
146
148
  """
147
149
  return len(self.name) > 0
148
150
 
149
- def __str__(self):
151
+ def __str__(self) -> str:
150
152
  """
151
153
  Creates the string representation of self
152
154
  :return: string
@@ -157,7 +159,7 @@ class DID(object):
157
159
  return self.scope
158
160
  return self.name
159
161
 
160
- def __eq__(self, other):
162
+ def __eq__(self, other: Union[str, "DID"]) -> bool:
161
163
  """
162
164
  Equality comparison with another object
163
165
  :return: bool
@@ -172,14 +174,14 @@ class DID(object):
172
174
 
173
175
  return self.scope == other.scope and self.name == other.name
174
176
 
175
- def __ne__(self, other):
177
+ def __ne__(self, other: Union[str, "DID"]) -> bool:
176
178
  """
177
179
  Inequality comparison with another object
178
180
  :return: bool
179
181
  """
180
182
  return not self.__eq__(other)
181
183
 
182
- def __hash__(self):
184
+ def __hash__(self) -> int:
183
185
  """
184
186
  Uses the string representation of self to create a hash
185
187
  :return: int