Skip to content

Commit d9aa1d4

Browse files
committed
feat: Require optional parameters to be keyword-specified
BREAKING CHANGE: Keyword-specific optional parameters are new in Python3
1 parent 3852c18 commit d9aa1d4

13 files changed

+35
-22
lines changed

ibm_cloud_sdk_core/api_exception.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class ApiException(Exception):
3232
global_transaction_id (str, optional): Globally unique id the service endpoint has given a transaction.
3333
"""
3434

35-
def __init__(self, code: int, message: Optional[str] = None, http_response: Optional[Response] = None):
35+
def __init__(self, code: int, *, message: Optional[str] = None, http_response: Optional[Response] = None):
3636
# Call the base class constructor with the parameters it needs
3737
super(ApiException, self).__init__(message)
3838
self.message = message

ibm_cloud_sdk_core/authenticators/cp4d_authenticator.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,13 @@ def __init__(self,
5656
username: str,
5757
password: str,
5858
url: str,
59+
*,
5960
disable_ssl_verification: bool = False,
6061
headers: Optional[Dict[str, str]] = None,
6162
proxies: Optional[Dict[str, str]] = None):
6263
self.token_manager = CP4DTokenManager(
63-
username, password, url, disable_ssl_verification, headers, proxies)
64+
username, password, url, disable_ssl_verification=disable_ssl_verification,
65+
headers=headers, proxies=proxies)
6466
self.validate()
6567

6668
def validate(self):

ibm_cloud_sdk_core/authenticators/iam_authenticator.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,17 @@ class IAMAuthenticator(Authenticator):
5656

5757
def __init__(self,
5858
apikey: str,
59+
*,
5960
url: Optional[str] = None,
6061
client_id: Optional[str] = None,
6162
client_secret: Optional[str] = None,
6263
disable_ssl_verification: Optional[bool] = False,
6364
headers: Optional[Dict[str, str]] = None,
6465
proxies: Optional[Dict[str, str]] = None):
6566
self.token_manager = IAMTokenManager(
66-
apikey, url, client_id, client_secret, disable_ssl_verification,
67-
headers, proxies)
67+
apikey, url=url, client_id=client_id, client_secret=client_secret,
68+
disable_ssl_verification=disable_ssl_verification,
69+
headers=headers, proxies=proxies)
6870
self.validate()
6971

7072
def validate(self):

ibm_cloud_sdk_core/base_service.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ class BaseService:
6565
'disable_ssl_verification option of the authenticator.'
6666

6767
def __init__(self,
68+
*,
6869
service_url: str = None,
6970
authenticator: Authenticator = None,
7071
disable_ssl_verification: bool = False):
@@ -218,8 +219,8 @@ def send(self, request: requests.Request, **kwargs) -> DetailedResponse:
218219
result = response.json()
219220
except:
220221
result = response
221-
return DetailedResponse(result, response.headers,
222-
response.status_code)
222+
return DetailedResponse(response=result, headers=response.headers,
223+
status_code=response.status_code)
223224

224225
raise ApiException(
225226
response.status_code, http_response=response)
@@ -237,6 +238,7 @@ def send(self, request: requests.Request, **kwargs) -> DetailedResponse:
237238
def prepare_request(self,
238239
method: str,
239240
url: str,
241+
*,
240242
headers: Optional[dict] = None,
241243
params: Optional[dict] = None,
242244
data: Optional[Union[str, dict]] = None,

ibm_cloud_sdk_core/cp4d_token_manager.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ def __init__(self,
5252
username: str,
5353
password: str,
5454
url: str,
55+
*,
5556
disable_ssl_verification: bool = False,
5657
headers: Optional[Dict[str, str]] = None,
5758
proxies: Optional[Dict[str, str]] = None):
@@ -61,8 +62,8 @@ def __init__(self,
6162
url = url + '/v1/preauth/validateAuth'
6263
self.headers = headers
6364
self.proxies = proxies
64-
super(CP4DTokenManager, self).__init__(url, disable_ssl_verification,
65-
self.TOKEN_NAME)
65+
super(CP4DTokenManager, self).__init__(url, disable_ssl_verification=disable_ssl_verification,
66+
token_name=self.TOKEN_NAME)
6667

6768
def request_token(self) -> dict:
6869
"""Makes a request for a token.

ibm_cloud_sdk_core/detailed_response.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class DetailedResponse:
3434
3535
"""
3636
def __init__(self,
37+
*,
3738
response: Optional[requests.Response] = None,
3839
headers: Optional[Dict[str, str]] = None,
3940
status_code: Optional[int] = None):

ibm_cloud_sdk_core/iam_token_manager.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class IAMTokenManager(JWTTokenManager):
6363

6464
def __init__(self,
6565
apikey: str,
66+
*,
6667
url: Optional[str] = None,
6768
client_id: Optional[str] = None,
6869
client_secret: Optional[str] = None,
@@ -76,7 +77,7 @@ def __init__(self,
7677
self.headers = headers
7778
self.proxies = proxies
7879
super(IAMTokenManager, self).__init__(
79-
self.url, disable_ssl_verification, self.TOKEN_NAME)
80+
self.url, disable_ssl_verification=disable_ssl_verification, token_name=self.TOKEN_NAME)
8081

8182
def request_token(self) -> dict:
8283
"""Request an IAM OAuth token given an API Key.

ibm_cloud_sdk_core/jwt_token_manager.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class JWTTokenManager:
5353

5454
# pylint: disable=too-many-instance-attributes
5555

56-
def __init__(self, url: str, disable_ssl_verification: bool = False, token_name: Optional[str] = None):
56+
def __init__(self, url: str, *, disable_ssl_verification: bool = False, token_name: Optional[str] = None):
5757
self.url = url
5858
self.disable_ssl_verification = disable_ssl_verification
5959
self.token_name = token_name
@@ -200,6 +200,7 @@ def _save_token_info(self, token_response):
200200
def _request(self,
201201
method,
202202
url,
203+
*,
203204
headers=None,
204205
params=None,
205206
data=None,

ibm_cloud_sdk_core/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ def __read_from_env_variables(service_name: str) -> dict:
197197
_parse_key_and_update_config(config, service_name, key, value)
198198
return config
199199

200-
def __read_from_credential_file(service_name: str, separator: str = '=') -> dict:
200+
def __read_from_credential_file(service_name: str, *, separator: str = '=') -> dict:
201201
"""Return a config object based on credentials file for a service.
202202
203203
Args:

test/test_base_service.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,7 @@ def test_service_url_not_set():
524524
assert str(err.value) == 'The service_url is required'
525525

526526
def test_setting_proxy():
527-
service = BaseService('test', authenticator=IAMAuthenticator('wonder woman'))
527+
service = BaseService(service_url='test', authenticator=IAMAuthenticator('wonder woman'))
528528
assert service.authenticator is not None
529529
assert service.authenticator.token_manager.http_config == {}
530530

@@ -536,7 +536,7 @@ def test_setting_proxy():
536536
service.set_http_config(http_config)
537537
assert service.authenticator.token_manager.http_config == http_config
538538

539-
service2 = BaseService('test', authenticator=BasicAuthenticator('marvellous', 'mrs maisel'))
539+
service2 = BaseService(service_url='test', authenticator=BasicAuthenticator('marvellous', 'mrs maisel'))
540540
service2.set_http_config(http_config)
541541
assert service2.authenticator is not None
542542

@@ -551,7 +551,7 @@ def test_configure_service():
551551
assert isinstance(service.get_authenticator(), NoAuthAuthenticator)
552552

553553
def test_configure_service_error():
554-
service = BaseService('v1', authenticator=NoAuthAuthenticator())
554+
service = BaseService(service_url='v1', authenticator=NoAuthAuthenticator())
555555
with pytest.raises(ValueError) as err:
556556
service.configure_service(None)
557557
assert str(err.value) == 'Service_name must be of type string.'

test/test_detailed_response.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ def test_detailed_response_dict():
1919
content_type='application/json')
2020

2121
mock_response = requests.get('https://test.com')
22-
detailed_response = DetailedResponse(mock_response.json(), mock_response.headers, mock_response.status_code)
22+
detailed_response = DetailedResponse(response=mock_response.json(), headers=mock_response.headers,
23+
status_code=mock_response.status_code)
2324
assert detailed_response is not None
2425
assert detailed_response.get_result() == {'foobar': 'baz'}
2526
assert detailed_response.get_headers() == {u'Content-Type': 'application/json'}
@@ -39,7 +40,8 @@ def test_detailed_response_list():
3940
content_type='application/json')
4041

4142
mock_response = requests.get('https://test.com')
42-
detailed_response = DetailedResponse(mock_response.json(), mock_response.headers, mock_response.status_code)
43+
detailed_response = DetailedResponse(response=mock_response.json(), headers=mock_response.headers,
44+
status_code=mock_response.status_code)
4345
assert detailed_response is not None
4446
assert detailed_response.get_result() == ['foobar', 'baz']
4547
assert detailed_response.get_headers() == {u'Content-Type': 'application/json'}

test/test_iam_token_manager.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def test_request_token_auth_in_ctor():
6060
default_auth_header = 'Basic Yng6Yng='
6161
responses.add(responses.POST, url=iam_url, body=response, status=200)
6262

63-
token_manager = IAMTokenManager("apikey", iam_url, 'foo', 'bar')
63+
token_manager = IAMTokenManager("apikey", url=iam_url, client_id='foo', client_secret='bar')
6464
token_manager.request_token()
6565

6666
assert len(responses.calls) == 1
@@ -112,7 +112,7 @@ def test_request_token_auth_in_ctor_client_id_only():
112112
}"""
113113
responses.add(responses.POST, url=iam_url, body=response, status=200)
114114

115-
token_manager = IAMTokenManager("iam_apikey", iam_url, 'foo')
115+
token_manager = IAMTokenManager("iam_apikey", url=iam_url, client_id='foo')
116116
token_manager.request_token()
117117

118118
assert len(responses.calls) == 1
@@ -132,7 +132,7 @@ def test_request_token_auth_in_ctor_secret_only():
132132
}"""
133133
responses.add(responses.POST, url=iam_url, body=response, status=200)
134134

135-
token_manager = IAMTokenManager("iam_apikey", iam_url, None, 'bar')
135+
token_manager = IAMTokenManager("iam_apikey", url=iam_url, client_id=None, client_secret='bar')
136136
token_manager.request_token()
137137

138138
assert len(responses.calls) == 1

test/test_jwt_token_manager.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ def __init__(self, url=None, access_token=None):
1111
self.url = url
1212
self.access_token = access_token
1313
self.request_count = 0 # just for tests to see how many times request was called
14-
super(JWTTokenManagerMockImpl, self).__init__(url, access_token, 'access_token')
14+
super(JWTTokenManagerMockImpl, self).__init__(url, disable_ssl_verification=access_token,
15+
token_name='access_token')
1516

1617
def request_token(self):
1718
self.request_count += 1
@@ -81,7 +82,7 @@ def test_paced_get_token():
8182
assert token_manager.request_count == 1
8283

8384
def test_is_token_expired():
84-
token_manager = JWTTokenManagerMockImpl(None, None)
85+
token_manager = JWTTokenManagerMockImpl(None, access_token=None)
8586
assert token_manager._is_token_expired() is True
8687
token_manager.expire_time = _get_current_time() + 3600
8788
assert token_manager._is_token_expired() is False
@@ -90,7 +91,7 @@ def test_is_token_expired():
9091

9192
def test_not_implemented_error():
9293
with pytest.raises(NotImplementedError) as err:
93-
token_manager = JWTTokenManager(None, None)
94+
token_manager = JWTTokenManager(None, disable_ssl_verification=None)
9495
token_manager.request_token()
9596
assert str(err.value) == 'request_token MUST be overridden by a subclass of JWTTokenManager.'
9697

0 commit comments

Comments
 (0)