Skip to content
This repository was archived by the owner on Jul 28, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 3 additions & 19 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ stage_linux: &stage_linux
<<: *stage_generic
os: linux
language: python
python: 3.5
python: 3.6

stage_osx: &stage_osx
<<: *stage_generic
Expand Down Expand Up @@ -82,9 +82,6 @@ stage_win: &stage_win
|
export PATH="/c/Python${PYTHON_VERSION}:/c/Python${PYTHON_VERSION}/Scripts:${PATH}"
case $PYTHON_VERSION in
35)
choco install python --version 3.5.4
;;
36)
choco install python --version 3.6.5
;;
Expand Down Expand Up @@ -115,7 +112,7 @@ jobs:
include:
# "lint and and pure python test" stage
###########################################################################
# Linter and style check (GNU/Linux, Python 3.5)
# Linter and style check (GNU/Linux, Python 3.7)
- stage: lint and pure python test
<<: *stage_linux
if: type != cron
Expand All @@ -129,7 +126,7 @@ jobs:
if: type != cron
script: make mypy

# Run the tests against without compilation (GNU/Linux, Python 3.5)
# Run the tests against without compilation (GNU/Linux, Python 3.6)
- stage: lint and pure python test
<<: *stage_linux
if: type != cron
Expand All @@ -156,14 +153,6 @@ jobs:
dist: xenial
python: 3.8

# OSX, Python 3.5.6 (via pyenv)
- stage: test
<<: *stage_osx
if: type != cron
env:
- MPLBACKEND=ps
- PYTHON_VERSION=3.5.6

# OSX, Python 3.6.5 (via pyenv)
- stage: test
<<: *stage_osx
Expand Down Expand Up @@ -228,11 +217,6 @@ jobs:
<<: *stage_win
env:
- PYTHON_VERSION=36
# Windows, Python 3.5
- if: type = cron
<<: *stage_win
env:
- PYTHON_VERSION=35
- if: tag IS present
language: python
python: "3.6"
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ lint:
pylint -rn qiskit/providers/ibmq test

mypy:
mypy --module qiskit.providers.ibmq --show-error-codes
mypy --module qiskit.providers.ibmq --show-error-codes --no-site-packages

style:
pycodestyle qiskit test
Expand Down
8 changes: 2 additions & 6 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ jobs:
pool: {vmImage: 'vs2017-win2016'}
strategy:
matrix:
Python35:
python.version: '3.5'
Python36:
python.version: '3.6'
Python37:
Expand Down Expand Up @@ -42,10 +40,8 @@ jobs:
condition: eq(variables['Build.Reason'], 'Schedule')
strategy:
matrix:
Python35:
python.version: '3.5'
# Python36:
# python.version: '3.6'
Python36:
python.version: '3.6'
# Python37:
# python.version: '3.7'
steps:
Expand Down
3 changes: 1 addition & 2 deletions qiskit/providers/ibmq/api/clients/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
import time

from typing import List, Dict, Any, Optional, Union
# Disabled unused-import because datetime is used only for type hints.
from datetime import datetime # pylint: disable=unused-import
from datetime import datetime

from qiskit.providers.ibmq.apiconstants import (API_JOB_FINAL_STATES, ApiJobStatus,
ApiJobShareLevel)
Expand Down
4 changes: 2 additions & 2 deletions qiskit/providers/ibmq/api/clients/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

"""Client for accessing IBM Quantum Experience authentication services."""

from typing import Dict, List, Optional, Any
from typing import Dict, List, Optional, Any, Union
from requests.exceptions import RequestException

from ..exceptions import AuthenticationLicenseError, RequestsApiError
Expand Down Expand Up @@ -141,7 +141,7 @@ def user_hubs(self) -> List[Dict[str, str]]:

# Miscellaneous public functions.

def api_version(self) -> Dict[str, str]:
def api_version(self) -> Dict[str, Union[str, bool]]:
"""Return the version of the API.

Returns:
Expand Down
69 changes: 26 additions & 43 deletions qiskit/providers/ibmq/api/clients/websocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@
import logging
import time
from abc import ABC, abstractmethod
from typing import Dict, Union, Generator, Optional, Any
from typing import Dict, Union, Optional, Any
from concurrent import futures
from ssl import SSLError
import warnings

import nest_asyncio
from websockets import connect, ConnectionClosed
Expand Down Expand Up @@ -57,10 +56,6 @@
except RuntimeError:
LOOP = asyncio.new_event_loop()
nest_asyncio.apply(LOOP)
# TODO Replace coroutine with async def once Python 3.5 is dropped.
# Also can upgrade to websocket 8 to avoid other deprecation warning.
warnings.filterwarnings("ignore", category=DeprecationWarning,
message="\"@coroutine\" decorator is deprecated")


class WebsocketMessage(ABC):
Expand Down Expand Up @@ -151,8 +146,7 @@ def __init__(self, websocket_url: str, access_token: str) -> None:
self.websocket_url = websocket_url.rstrip('/')
self.access_token = access_token

@asyncio.coroutine
def _connect(self, url: str) -> Generator[Any, None, WebSocketClientProtocol]:
async def _connect(self, url: str) -> WebSocketClientProtocol:
"""Authenticate with the websocket server and return the connection.

Returns:
Expand All @@ -168,10 +162,7 @@ def _connect(self, url: str) -> Generator[Any, None, WebSocketClientProtocol]:
"""
try:
logger.debug('Starting new websocket connection: %s', url)
with warnings.catch_warnings():
# Suppress websockets deprecation warnings until the fix is available
warnings.filterwarnings("ignore", category=DeprecationWarning)
websocket = yield from connect(url)
websocket = await connect(url)

# Isolate specific exceptions, so they are not retried in `get_job_status`.
except (SSLError, InvalidURI) as ex:
Expand All @@ -188,21 +179,19 @@ def _connect(self, url: str) -> Generator[Any, None, WebSocketClientProtocol]:
try:
# Authenticate against the server.
auth_request = self._authentication_message()
with warnings.catch_warnings():
# Suppress websockets deprecation warnings until the fix is available
warnings.filterwarnings("ignore", category=DeprecationWarning)
yield from websocket.send(auth_request.as_json())
await websocket.send(auth_request.as_json())

# Verify that the server acknowledged our authentication.
auth_response_raw = yield from websocket.recv()
# Verify that the server acknowledged our authentication.
auth_response_raw = await websocket.recv()

auth_response = WebsocketResponseMethod.from_bytes(auth_response_raw)
auth_response = WebsocketResponseMethod.from_bytes(
auth_response_raw) # type: ignore[arg-type]

if auth_response.type_ != 'authenticated':
raise WebsocketIBMQProtocolError('Failed to authenticate against the server: {}'
.format(auth_response.as_json()))
except ConnectionClosed as ex:
yield from websocket.close()
await websocket.close()
exception_to_raise = WebsocketAuthenticationError(
'Unexpected error occurred when authenticating against the server.')

Expand All @@ -212,15 +201,14 @@ def _connect(self, url: str) -> Generator[Any, None, WebSocketClientProtocol]:

return websocket

@asyncio.coroutine
def get_job_status(
async def get_job_status(
self,
job_id: str,
timeout: Optional[float] = None,
retries: int = 5,
backoff_factor: float = 0.5,
status_queue: Optional[RefreshQueue] = None
) -> Generator[Any, None, Dict[str, str]]:
) -> Dict[str, str]:
"""Return the status of a job.

Read status messages from the server, which are issued at regular
Expand Down Expand Up @@ -269,24 +257,22 @@ def get_job_status(

while current_retry_attempt <= retries:
try:
websocket = yield from self._connect(url)
websocket = await self._connect(url)
# Read messages from the server until the connection is closed or
# a timeout has been reached.
while True:
try:
with warnings.catch_warnings():
# Suppress websockets deprecation warnings until the fix is available
warnings.filterwarnings("ignore", category=DeprecationWarning)
if timeout:
response_raw = yield from asyncio.wait_for(
websocket.recv(), timeout=timeout)

# Decrease the timeout.
timeout = original_timeout - (time.time() - start_time)
else:
response_raw = yield from websocket.recv()

response = WebsocketResponseMethod.from_bytes(response_raw)
if timeout:
response_raw = await asyncio.wait_for(
websocket.recv(), timeout=timeout)

# Decrease the timeout.
timeout = original_timeout - (time.time() - start_time)
else:
response_raw = await websocket.recv()

response = WebsocketResponseMethod.from_bytes(
response_raw) # type: ignore[arg-type]
if logger.getEffectiveLevel() is logging.DEBUG:
logger.debug('Received message from websocket: %s',
filter_data(response.get_data()))
Expand Down Expand Up @@ -356,16 +342,13 @@ def get_job_status(
backoff_time = self._backoff_time(backoff_factor, current_retry_attempt)
logger.info('Retrying get_job_status via websocket after %s seconds: '
'Attempt #%s', backoff_time, current_retry_attempt)
yield from asyncio.sleep(backoff_time) # Block asyncio loop for given backoff time.
await asyncio.sleep(backoff_time) # Block asyncio loop for given backoff time.

continue # Continues next iteration after `finally` block.

finally:
with warnings.catch_warnings():
# Suppress websockets deprecation warnings until the fix is available
warnings.filterwarnings("ignore", category=DeprecationWarning)
if websocket is not None:
yield from websocket.close()
if websocket is not None:
await websocket.close()

# Execution should not reach here, sanity check.
exception_message = 'Max retries exceeded: Failed to establish a websocket ' \
Expand Down
2 changes: 1 addition & 1 deletion qiskit/providers/ibmq/api/rest/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import json
from typing import Dict, Optional, Any, List
from datetime import datetime # pylint: disable=unused-import
from datetime import datetime

from .base import RestAdapterBase
from ..session import RetrySession
Expand Down
4 changes: 2 additions & 2 deletions qiskit/providers/ibmq/backendjoblimit.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

"""Job limit information related to a backend."""

from typing import Any
from typing import Any, Dict


class BackendJobLimit:
Expand All @@ -31,7 +31,7 @@ class BackendJobLimit:
this provider.
"""

_data = {}
_data = {} # type:Dict

def __init__(self, maximum_jobs: int, running_jobs: int, **kwargs: Any) -> None:
"""BackendJobLimit constructor.
Expand Down
4 changes: 2 additions & 2 deletions qiskit/providers/ibmq/backendreservation.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

"""Reservation information related to a backend."""

from typing import Optional
from typing import Optional, Any
from datetime import datetime


Expand Down Expand Up @@ -87,7 +87,7 @@ def __repr__(self) -> str:
out_str += ')>'
return out_str

def __eq__(self, other):
def __eq__(self, other: Any) -> bool:
if isinstance(other, BackendReservation) and self.backend_name == other.backend_name:
if self.reservation_id and self.reservation_id == other.reservation_id:
return True
Expand Down
11 changes: 6 additions & 5 deletions qiskit/providers/ibmq/ibmqbackendservice.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
from typing import Dict, List, Callable, Optional, Any, Union
from datetime import datetime

from qiskit.providers import JobStatus, QiskitBackendNotFoundError # type: ignore[attr-defined]
from qiskit.providers.jobstatus import JobStatus
from qiskit.providers.exceptions import QiskitBackendNotFoundError
from qiskit.providers.providerutils import filter_backends
from qiskit.providers.ibmq import accountprovider # pylint: disable=unused-import

Expand Down Expand Up @@ -359,13 +360,13 @@ def _update_creation_date_filter(
lt_list.append(cur_dt_filter.pop('between')[1])
lte_dt = min(lt_list) if lt_list else None

new_dt_filter = {}
new_dt_filter = {} # type: Dict[str, Union[str, List[str]]]
if gte_dt and lte_dt:
new_dt_filter['between'] = [gte_dt, lte_dt]
elif gte_dt:
new_dt_filter['gte'] = gte_dt # type: ignore[assignment]
new_dt_filter['gte'] = gte_dt
elif lte_dt:
new_dt_filter['lte'] = lte_dt # type: ignore[assignment]
new_dt_filter['lte'] = lte_dt

return new_dt_filter

Expand Down Expand Up @@ -431,7 +432,7 @@ def _get_status_filter(self, status: Union[JobStatus, str]) -> Dict[str, Any]:
elif status == JobStatus.DONE:
_status_filter = {'status': ApiJobStatus.COMPLETED.value}
elif status == JobStatus.ERROR:
_status_filter = {'status': {'regexp': '^ERROR'}} # type: ignore[assignment]
_status_filter = {'status': {'regexp': '^ERROR'}}
else:
raise IBMQBackendValueError(
'"{}" is not a valid status value. Valid values are {}'.format(
Expand Down
4 changes: 2 additions & 2 deletions qiskit/providers/ibmq/job/ibmqjob.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ class IBMQJob(BaseJob):
which is a supported attribute.
"""

_data = {}
_data = {} # type: Dict

_executor = futures.ThreadPoolExecutor()
"""Threads used for asynchronous processing."""
Expand Down Expand Up @@ -890,7 +890,7 @@ def _wait_for_completion(

return self._status in required_status

def _retrieve_result(self, refresh: bool = False):
def _retrieve_result(self, refresh: bool = False) -> None:
"""Retrieve the job result response.

Args:
Expand Down
4 changes: 2 additions & 2 deletions qiskit/providers/ibmq/job/queueinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

"""Queue information for a job."""

from typing import Any, Optional, Union
from typing import Any, Optional, Union, Dict
from datetime import datetime
import warnings

Expand All @@ -27,7 +27,7 @@
class QueueInfo:
"""Queue information for a job."""

_data = {}
_data = {} # type: Dict

def __init__(
self,
Expand Down
Loading