Skip to content

Commit

Permalink
[Python] Migrate from yapf to black (#33138)
Browse files Browse the repository at this point in the history
- Switched  from yapf to black
- Reconfigure isort for black
- Resolve black/pylint idiosyncrasies 

Note: I used `--experimental-string-processing` because black was
producing "implicit string concatenation", similar to what described
here: psf/black#1837. While currently this
feature is experimental, it will be enabled by default:
psf/black#2188. After running black with the
new string processing so that the generated code merges these `"hello" "
world"` strings concatenations, then I removed
`--experimental-string-processing` for stability, and regenerated the
code again.

To the reviewer: don't even try to open "Files Changed" tab 😄 It's
better to review commit-by-commit, and ignore `run black and isort`.
  • Loading branch information
sergiitk committed Jun 9, 2023
1 parent e9e5dc0 commit de6ed9b
Show file tree
Hide file tree
Showing 573 changed files with 42,016 additions and 29,841 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Expand Up @@ -23,7 +23,7 @@ src/python/grpcio_*/=*
src/python/grpcio_*/build/
src/python/grpcio_*/LICENSE
src/python/grpcio_status/grpc_status/google/rpc/status.proto
yapf_virtual_environment/
black_virtual_environment/
isort_virtual_environment/

# Node installation output
Expand Down
51 changes: 51 additions & 0 deletions black.toml
@@ -0,0 +1,51 @@
[tool.black]
line-length = 80
target-version = [
"py37",
"py38",
"py39",
"py310",
"py311",
]
extend-exclude = '''
# A regex preceded with ^/ will apply only to files and directories
# in the root of the project.
(
site-packages
| test/cpp/naming/resolver_component_tests_runner.py # AUTO-GENERATED
# AUTO-GENERATED from a template:
| grpc_version.py
| src/python/grpcio/grpc_core_dependencies.py
| src/python/grpcio/grpc/_grpcio_metadata.py
# AUTO-GENERATED BY make_grpcio_tools.py
| tools/distrib/python/grpcio_tools/protoc_lib_deps.py
| .*_pb2.py # autogenerated Protocol Buffer files
| .*_pb2_grpc.py # autogenerated Protocol Buffer gRPC files
)
'''

[tool.isort]
profile = "black"
line_length = 80
src_paths = [
"examples/python/data_transmission",
"examples/python/async_streaming",
"tools/run_tests/xds_k8s_test_driver",
"src/python/grpcio_tests",
"tools/run_tests",
]
known_first_party = [
"examples",
"src",
]
known_third_party = ["grpc"]
skip_glob = [
"third_party/*",
"*/env/*",
"*pb2*.py",
"*pb2*.pyi",
"**/site-packages/**/*",
]
single_line_exclusions = ["typing"]
force_single_line = true
force_sort_within_sections = true
40 changes: 25 additions & 15 deletions examples/python/async_streaming/client.py
Expand Up @@ -24,9 +24,12 @@


class CallMaker:

def __init__(self, executor: ThreadPoolExecutor, channel: grpc.Channel,
phone_number: str) -> None:
def __init__(
self,
executor: ThreadPoolExecutor,
channel: grpc.Channel,
phone_number: str,
) -> None:
self._executor = executor
self._channel = channel
self._stub = phone_pb2_grpc.PhoneStub(self._channel)
Expand All @@ -39,8 +42,8 @@ def __init__(self, executor: ThreadPoolExecutor, channel: grpc.Channel,
self._consumer_future = None

def _response_watcher(
self,
response_iterator: Iterator[phone_pb2.StreamCallResponse]) -> None:
self, response_iterator: Iterator[phone_pb2.StreamCallResponse]
) -> None:
try:
for response in response_iterator:
# NOTE: All fields in Proto3 are optional. This is the recommended way
Expand All @@ -52,7 +55,8 @@ def _response_watcher(
self._on_call_state(response.call_state.state)
else:
raise RuntimeError(
"Received StreamCallResponse without call_info and call_state"
"Received StreamCallResponse without call_info and"
" call_state"
)
except Exception as e:
self._peer_responded.set()
Expand All @@ -63,8 +67,11 @@ def _on_call_info(self, call_info: phone_pb2.CallInfo) -> None:
self._audio_session_link = call_info.media

def _on_call_state(self, call_state: phone_pb2.CallState.State) -> None:
logging.info("Call toward [%s] enters [%s] state", self._phone_number,
phone_pb2.CallState.State.Name(call_state))
logging.info(
"Call toward [%s] enters [%s] state",
self._phone_number,
phone_pb2.CallState.State.Name(call_state),
)
self._call_state = call_state
if call_state == phone_pb2.CallState.State.ACTIVE:
self._peer_responded.set()
Expand All @@ -77,8 +84,9 @@ def call(self) -> None:
request.phone_number = self._phone_number
response_iterator = self._stub.StreamCall(iter((request,)))
# Instead of consuming the response on current thread, spawn a consumption thread.
self._consumer_future = self._executor.submit(self._response_watcher,
response_iterator)
self._consumer_future = self._executor.submit(
self._response_watcher, response_iterator
)

def wait_peer(self) -> bool:
logging.info("Waiting for peer to connect [%s]...", self._phone_number)
Expand All @@ -95,8 +103,9 @@ def audio_session(self) -> None:
logging.info("Audio session finished [%s]", self._audio_session_link)


def process_call(executor: ThreadPoolExecutor, channel: grpc.Channel,
phone_number: str) -> None:
def process_call(
executor: ThreadPoolExecutor, channel: grpc.Channel, phone_number: str
) -> None:
call_maker = CallMaker(executor, channel, phone_number)
call_maker.call()
if call_maker.wait_peer():
Expand All @@ -109,11 +118,12 @@ def process_call(executor: ThreadPoolExecutor, channel: grpc.Channel,
def run():
executor = ThreadPoolExecutor()
with grpc.insecure_channel("localhost:50051") as channel:
future = executor.submit(process_call, executor, channel,
"555-0100-XXXX")
future = executor.submit(
process_call, executor, channel, "555-0100-XXXX"
)
future.result()


if __name__ == '__main__':
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
run()
15 changes: 9 additions & 6 deletions examples/python/async_streaming/server.py
Expand Up @@ -26,14 +26,14 @@


def create_state_response(
call_state: phone_pb2.CallState.State) -> phone_pb2.StreamCallResponse:
call_state: phone_pb2.CallState.State,
) -> phone_pb2.StreamCallResponse:
response = phone_pb2.StreamCallResponse()
response.call_state.state = call_state
return response


class Phone(phone_pb2_grpc.PhoneServicer):

def __init__(self):
self._id_counter = 0
self._lock = threading.RLock()
Expand All @@ -51,13 +51,16 @@ def _clean_call_session(self, call_info: phone_pb2.CallInfo) -> None:
logging.info("Call session cleaned [%s]", MessageToJson(call_info))

def StreamCall(
self, request_iterator: Iterable[phone_pb2.StreamCallRequest],
context: grpc.ServicerContext
self,
request_iterator: Iterable[phone_pb2.StreamCallRequest],
context: grpc.ServicerContext,
) -> Iterable[phone_pb2.StreamCallResponse]:
try:
request = next(request_iterator)
logging.info("Received a phone call request for number [%s]",
request.phone_number)
logging.info(
"Received a phone call request for number [%s]",
request.phone_number,
)
except StopIteration:
raise RuntimeError("Failed to receive call request")
# Simulate the acceptance of call request
Expand Down
8 changes: 4 additions & 4 deletions examples/python/auth/_credentials.py
Expand Up @@ -18,10 +18,10 @@

def _load_credential_from_file(filepath):
real_path = os.path.join(os.path.dirname(__file__), filepath)
with open(real_path, 'rb') as f:
with open(real_path, "rb") as f:
return f.read()


SERVER_CERTIFICATE = _load_credential_from_file('credentials/localhost.crt')
SERVER_CERTIFICATE_KEY = _load_credential_from_file('credentials/localhost.key')
ROOT_CERTIFICATE = _load_credential_from_file('credentials/root.crt')
SERVER_CERTIFICATE = _load_credential_from_file("credentials/localhost.crt")
SERVER_CERTIFICATE_KEY = _load_credential_from_file("credentials/localhost.key")
ROOT_CERTIFICATE = _load_credential_from_file("credentials/root.crt")
43 changes: 25 additions & 18 deletions examples/python/auth/async_customized_auth_client.py
Expand Up @@ -21,19 +21,22 @@
import grpc

helloworld_pb2, helloworld_pb2_grpc = grpc.protos_and_services(
"helloworld.proto")
"helloworld.proto"
)

_LOGGER = logging.getLogger(__name__)
_LOGGER.setLevel(logging.INFO)

_SERVER_ADDR_TEMPLATE = 'localhost:%d'
_SIGNATURE_HEADER_KEY = 'x-signature'
_SERVER_ADDR_TEMPLATE = "localhost:%d"
_SIGNATURE_HEADER_KEY = "x-signature"


class AuthGateway(grpc.AuthMetadataPlugin):

def __call__(self, context: grpc.AuthMetadataContext,
callback: grpc.AuthMetadataPluginCallback) -> None:
def __call__(
self,
context: grpc.AuthMetadataContext,
callback: grpc.AuthMetadataPluginCallback,
) -> None:
"""Implements authentication by passing metadata to a callback.
Implementations of this method must not block.
Expand All @@ -54,11 +57,13 @@ def __call__(self, context: grpc.AuthMetadataContext,

def create_client_channel(addr: str) -> grpc.aio.Channel:
# Call credential object will be invoked for every single RPC
call_credentials = grpc.metadata_call_credentials(AuthGateway(),
name='auth gateway')
call_credentials = grpc.metadata_call_credentials(
AuthGateway(), name="auth gateway"
)
# Channel credential will be valid for the entire channel
channel_credential = grpc.ssl_channel_credentials(
_credentials.ROOT_CERTIFICATE)
_credentials.ROOT_CERTIFICATE
)
# Combining channel credentials and call credentials together
composite_credentials = grpc.composite_channel_credentials(
channel_credential,
Expand All @@ -70,31 +75,33 @@ def create_client_channel(addr: str) -> grpc.aio.Channel:

async def send_rpc(channel: grpc.aio.Channel) -> helloworld_pb2.HelloReply:
stub = helloworld_pb2_grpc.GreeterStub(channel)
request = helloworld_pb2.HelloRequest(name='you')
request = helloworld_pb2.HelloRequest(name="you")
try:
response = await stub.SayHello(request)
except grpc.RpcError as rpc_error:
_LOGGER.error('Received error: %s', rpc_error)
_LOGGER.error("Received error: %s", rpc_error)
return rpc_error
else:
_LOGGER.info('Received message: %s', response)
_LOGGER.info("Received message: %s", response)
return response


async def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument('--port',
nargs='?',
type=int,
default=50051,
help='the address of server')
parser.add_argument(
"--port",
nargs="?",
type=int,
default=50051,
help="the address of server",
)
args = parser.parse_args()

channel = create_client_channel(_SERVER_ADDR_TEMPLATE % args.port)
await send_rpc(channel)
await channel.close()


if __name__ == '__main__':
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
asyncio.run(main())

0 comments on commit de6ed9b

Please sign in to comment.