You are viewing a plain text version of this content. The canonical link for it is here.
Posted to github@beam.apache.org by GitBox <gi...@apache.org> on 2022/04/01 22:45:06 UTC

[GitHub] [beam] robertwb commented on a change in pull request #16961: BEAM-13939: Restructure Protos to fix namespace conflicts

robertwb commented on a change in pull request #16961:
URL: https://github.com/apache/beam/pull/16961#discussion_r840952858



##########
File path: sdks/go/pkg/beam/transforms/stats/util_gen.tmpl
##########
@@ -23,4 +23,4 @@ package stats
 {{- with $x := .X }}
 //go:generate starcgen --package=stats --identifiers=countFn,keyedCountFn,meanFn{{- range $i, $t := $x -}},max{{$t.Name}}Fn,min{{$t.Name}}Fn,sum{{$t.Name}}Fn{{- end -}}
 {{end}}
-
+//go:generate gofmt -w stats.shims.go

Review comment:
       Restore trailing newline?

##########
File path: sdks/python/.yapfignore
##########
@@ -21,7 +21,7 @@ apache_beam/runners/dataflow/internal/clients/dataflow/dataflow_v1b3_messages.py
 apache_beam/io/gcp/internal/clients/storage/storage_v1_client.py
 apache_beam/io/gcp/internal/clients/storage/storage_v1_messages.py
 apache_beam/coders/proto2_coder_test_messages_pb2.py
-apache_beam/portability/api/*pb2*.py
+apache_beam/portability/api/*

Review comment:
       Can you confirm that we have only generated code in this subdirectory? (Does the ** pattern of "match all subdirectories not work?)

##########
File path: sdks/python/apache_beam/portability/api/__init__.py
##########
@@ -1,21 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-"""For internal use only; no backwards-compatibility guarantees.
-
-Automatically generated when running setup.py sdist or build[_py].

Review comment:
       I'm fine with this given the constraints. 

##########
File path: sdks/python/gen_protos.py
##########
@@ -15,40 +15,100 @@
 # limitations under the License.
 #
 
-"""Generates Python proto modules and grpc stubs for Beam protos."""
+"""
+Generates Python proto modules and grpc stubs for Beam protos.
+"""
+
 import contextlib
 import glob
 import inspect
 import logging
-import multiprocessing
 import os
 import platform
 import re
 import shutil
 import subprocess
 import sys
 import time
-import warnings
+from collections import defaultdict
 from importlib import import_module
 
 import pkg_resources
 
+LOG = logging.getLogger()
+LOG.setLevel(logging.INFO)
+
+LICENSE_HEADER = """

Review comment:
       I would just drop these two headers and skip the checks over adding logic to prepend them to the auto-generated files.

##########
File path: sdks/python/gen_protos.py
##########
@@ -227,167 +291,270 @@ def _find_protoc_gen_mypy():
   for path in search_paths:
     fullpath = os.path.join(path, fname)
     if os.path.exists(fullpath):
+      LOG.info('Found protoc_gen_mypy at %s' % fullpath)
       return fullpath
-  raise RuntimeError("Could not find %s in %s" %
-                     (fname, ', '.join(search_paths)))
+  raise RuntimeError(
+      "Could not find %s in %s" % (fname, ', '.join(search_paths)))
+
 
+def find_by_ext(root_dir, ext):
+  for root, _, files in os.walk(root_dir):
+    for file in files:
+      if file.endswith(ext):
+        yield clean_path(os.path.join(root, file))
 
-def generate_proto_files(force=False, log=None):
 
+def ensure_grpcio_exists():
   try:
-    import grpc_tools  # pylint: disable=unused-import
+    from grpc_tools import protoc  # pylint: disable=unused-import
   except ImportError:
-    warnings.warn('Installing grpcio-tools is recommended for development.')
+    if platform.system() == 'Windows':
+      # For Windows, grpcio-tools has to be installed manually.
+      raise RuntimeError(
+          'Cannot generate protos for Windows since grpcio-tools package is '
+          'not installed. Please install this package manually '
+          'using \'pip install grpcio-tools\'.')
+    return _install_grpcio_tools()
 
-  if log is None:
-    logging.basicConfig()
-    log = logging.getLogger(__name__)
-    log.setLevel(logging.INFO)
+  return ""

Review comment:
       Returning the empty string seems odd here--best to return None or omit it. (It would be natural to let PythonPath handle None as a no-op.)

##########
File path: sdks/python/gen_protos.py
##########
@@ -174,22 +239,20 @@ def write_message(self, message_name, message, indent=0):
         ctx.prepend('')
       return ctx.lines
 
-  pb2_files = [path for path in glob.glob(os.path.join(out_dir, '*_pb2.py'))]
-  api_path = os.path.dirname(pb2_files[0])
-  sys.path.insert(0, os.path.dirname(api_path))
+  pb2_files = list(glob.glob(os.path.join(out_dir, '*_pb2.py')))
 
-  def _import(m):
-    return import_module('api.%s' % m)
-
-  try:
-    beam_runner_api_pb2 = _import('beam_runner_api_pb2')
-    metrics_pb2 = _import('metrics_pb2')
+  with PythonPath(os.path.dirname(api_path), front=True) as _:

Review comment:
       The `as _` can be omitted (here and below). 

##########
File path: sdks/python/gen_protos.py
##########
@@ -15,40 +15,100 @@
 # limitations under the License.
 #
 
-"""Generates Python proto modules and grpc stubs for Beam protos."""
+"""
+Generates Python proto modules and grpc stubs for Beam protos.
+"""
+
 import contextlib
 import glob
 import inspect
 import logging
-import multiprocessing
 import os
 import platform
 import re
 import shutil
 import subprocess
 import sys
 import time
-import warnings
+from collections import defaultdict
 from importlib import import_module
 
 import pkg_resources
 
+LOG = logging.getLogger()
+LOG.setLevel(logging.INFO)
+
+LICENSE_HEADER = """
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+"""
+
+NO_PROMISES_NOTICE = """
+\"\"\"
+For internal use only; no backwards-compatibility guarantees.
+Automatically generated when running setup.py sdist or build[_py].
+\"\"\"
+"""
+
+
+def clean_path(path):
+  return os.path.realpath(os.path.abspath(path))
+
+
+# These paths are relative to the project root
 BEAM_PROTO_PATHS = [
-    os.path.join('..', '..', 'model', 'pipeline', 'src', 'main', 'proto'),
-    os.path.join('..', '..', 'model', 'job-management', 'src', 'main', 'proto'),
-    os.path.join('..', '..', 'model', 'fn-execution', 'src', 'main', 'proto'),
-    os.path.join('..', '..', 'model', 'interactive', 'src', 'main', 'proto'),
+    os.path.join('model', 'pipeline', 'src', 'main', 'proto'),
+    os.path.join('model', 'job-management', 'src', 'main', 'proto'),
+    os.path.join('model', 'fn-execution', 'src', 'main', 'proto'),
+    os.path.join('model', 'interactive', 'src', 'main', 'proto'),
 ]
 
-PYTHON_OUTPUT_PATH = os.path.join('apache_beam', 'portability', 'api')
+PYTHON_SDK_ROOT = os.path.dirname(clean_path(__file__))
+PROJECT_ROOT = clean_path(os.path.join(PYTHON_SDK_ROOT, '..', '..'))
+PYTHON_OUTPUT_PATH = os.path.join(
+    PYTHON_SDK_ROOT, 'apache_beam', 'portability', 'api')
 
 MODEL_RESOURCES = [
-    os.path.normpath('../../model/fn-execution/src/main/resources'\
-            + '/org/apache/beam/model/fnexecution/v1/standard_coders.yaml'),
+    os.path.normpath((
+        'model/fn-execution/src/main/resources/org/'
+        'apache/beam/model/fnexecution/v1/standard_coders.yaml')),
 ]
 
 
-def generate_urn_files(log, out_dir):
+class PythonPath(object):
+  def __init__(self, path: str, front: bool = False):
+    self._sys_path = sys.path.copy()

Review comment:
       Technically, this should probably be initialized on at `__enter__` rather that here.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@beam.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org