From 21a7cf965a679dcdfb9044a3cff2597f25379431 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Sat, 11 Apr 2015 18:24:24 -0700 Subject: [PATCH] Noramlize 'setup.py' to fit conventions: - Comply with flake8, except for indentation width, which is 2. - Move human-centric metadata to top of 'setup()' call. - Add Trove classifiers for supported Python versions. - Use 'find_packages()' + MANIFEST.in to avoid errors in listing modules and packages. Closes #131 and #161. --- python/MANIFEST.in | 14 ++++ python/setup.py | 169 ++++++++++++++++++++++----------------------- 2 files changed, 95 insertions(+), 88 deletions(-) create mode 100644 python/MANIFEST.in diff --git a/python/MANIFEST.in b/python/MANIFEST.in new file mode 100644 index 000000000..260888263 --- /dev/null +++ b/python/MANIFEST.in @@ -0,0 +1,14 @@ +prune google/protobuf/internal/import_test_package +exclude google/protobuf/internal/*_pb2.py +exclude google/protobuf/internal/*_test.py +exclude google/protobuf/internal/*.proto +exclude google/protobuf/internal/test_util.py + +recursive-exclude google *_test.py +recursive-exclude google *_test.proto +recursive-exclude google unittest*_pb2.py + +global-exclude *.dll +global-exclude *.pyc +global-exclude *.pyo +global-exclude *.so diff --git a/python/setup.py b/python/setup.py index 85c14894a..06aed94b7 100755 --- a/python/setup.py +++ b/python/setup.py @@ -8,27 +8,28 @@ import subprocess # We must use setuptools, not distutils, because we need to use the # namespace_packages option for the "google" package. try: - from setuptools import setup, Extension + from setuptools import setup, Extension, find_packages except ImportError: try: from ez_setup import use_setuptools use_setuptools() - from setuptools import setup, Extension + from setuptools import setup, Extension, find_packages except ImportError: sys.stderr.write( "Could not import setuptools; make sure you have setuptools or " - "ez_setup installed.\n") + "ez_setup installed.\n" + ) raise -from distutils.command.clean import clean as _clean -if sys.version_info[0] >= 3: - # Python 3 - from distutils.command.build_py import build_py_2to3 as _build_py -else: - # Python 2 - from distutils.command.build_py import build_py as _build_py -from distutils.spawn import find_executable -maintainer_email = "protobuf@googlegroups.com" +from distutils.command.clean import clean as _clean + +if sys.version_info[0] == 3: + # Python 3 + from distutils.command.build_py import build_py_2to3 as _build_py +else: + # Python 2 + from distutils.command.build_py import build_py as _build_py +from distutils.spawn import find_executable # Find the Protocol Compiler. if 'PROTOC' in os.environ and os.path.exists(os.environ['PROTOC']): @@ -44,13 +45,13 @@ elif os.path.exists("../vsprojects/Release/protoc.exe"): else: protoc = find_executable("protoc") + def GetVersion(): """Gets the version from google/protobuf/__init__.py - Do not import google.protobuf.__init__ directly, because an installed protobuf - library may be loaded instead. + Do not import google.protobuf.__init__ directly, because an installed + protobuf library may be loaded instead.""" - """ with open(os.path.join('google', 'protobuf', '__init__.py')) as version_file: exec(version_file.read()) return __version__ @@ -66,22 +67,24 @@ def generate_proto(source): if (not os.path.exists(output) or (os.path.exists(source) and os.path.getmtime(source) > os.path.getmtime(output))): - print ("Generating %s..." % output) + print("Generating %s..." % output) if not os.path.exists(source): sys.stderr.write("Can't find required file: %s\n" % source) sys.exit(-1) - if protoc == None: + if protoc is None: sys.stderr.write( - "protoc is not installed nor found in ../src. Please compile it " - "or install the binary package.\n") + "protoc is not installed nor found in ../src. " + "Please compile it or install the binary package.\n" + ) sys.exit(-1) - protoc_command = [ protoc, "-I../src", "-I.", "--python_out=.", source ] + protoc_command = [protoc, "-I../src", "-I.", "--python_out=.", source] if subprocess.call(protoc_command) != 0: sys.exit(-1) + def GenerateUnittestProtos(): generate_proto("../src/google/protobuf/unittest.proto") generate_proto("../src/google/protobuf/unittest_custom_options.proto") @@ -92,17 +95,18 @@ def GenerateUnittestProtos(): generate_proto("../src/google/protobuf/unittest_proto3_arena.proto") generate_proto("google/protobuf/internal/descriptor_pool_test1.proto") generate_proto("google/protobuf/internal/descriptor_pool_test2.proto") - generate_proto("google/protobuf/internal/test_bad_identifiers.proto") - generate_proto("google/protobuf/internal/missing_enum_values.proto") - generate_proto("google/protobuf/internal/more_extensions.proto") - generate_proto("google/protobuf/internal/more_extensions_dynamic.proto") - generate_proto("google/protobuf/internal/more_messages.proto") generate_proto("google/protobuf/internal/factory_test1.proto") generate_proto("google/protobuf/internal/factory_test2.proto") generate_proto("google/protobuf/internal/import_test_package/inner.proto") generate_proto("google/protobuf/internal/import_test_package/outer.proto") + generate_proto("google/protobuf/internal/missing_enum_values.proto") + generate_proto("google/protobuf/internal/more_extensions.proto") + generate_proto("google/protobuf/internal/more_extensions_dynamic.proto") + generate_proto("google/protobuf/internal/more_messages.proto") + generate_proto("google/protobuf/internal/test_bad_identifiers.proto") generate_proto("google/protobuf/pyext/python.proto") + class clean(_clean): def run(self): # Delete generated files in the code tree. @@ -110,12 +114,13 @@ class clean(_clean): for filename in filenames: filepath = os.path.join(dirpath, filename) if filepath.endswith("_pb2.py") or filepath.endswith(".pyc") or \ - filepath.endswith(".so") or filepath.endswith(".o") or \ - filepath.endswith('google/protobuf/compiler/__init__.py'): + filepath.endswith(".so") or filepath.endswith(".o") or \ + filepath.endswith('google/protobuf/compiler/__init__.py'): os.remove(filepath) # _clean is an old-style class, so super() doesn't work. _clean.run(self) + class build_py(_build_py): def run(self): # Generate necessary .proto file if it doesn't exist. @@ -132,11 +137,11 @@ class build_py(_build_py): # _build_py is an old-style class, so super() doesn't work. _build_py.run(self) # TODO(mrovner): Subclass to run 2to3 on some files only. - # Tracing what https://wiki.python.org/moin/PortingPythonToPy3k's "Approach 2" - # section on how to get 2to3 to run on source files during install under - # Python 3. This class seems like a good place to put logic that calls - # python3's distutils.util.run_2to3 on the subset of the files we have in our - # release that are subject to conversion. + # Tracing what https://wiki.python.org/moin/PortingPythonToPy3k's + # "Approach 2" section on how to get 2to3 to run on source files during + # install under Python 3. This class seems like a good place to put logic + # that calls python3's distutils.util.run_2to3 on the subset of the files we + # have in our release that are subject to conversion. # See code reference in previous code review. if __name__ == '__main__': @@ -145,61 +150,49 @@ if __name__ == '__main__': if cpp_impl in sys.argv: sys.argv.remove(cpp_impl) # C++ implementation extension - ext_module_list.append(Extension( - "google.protobuf.pyext._message", - [ "google/protobuf/pyext/descriptor.cc", - "google/protobuf/pyext/descriptor_containers.cc", - "google/protobuf/pyext/descriptor_pool.cc", - "google/protobuf/pyext/message.cc", - "google/protobuf/pyext/extension_dict.cc", - "google/protobuf/pyext/repeated_scalar_container.cc", - "google/protobuf/pyext/repeated_composite_container.cc" ], - define_macros=[('GOOGLE_PROTOBUF_HAS_ONEOF', '1')], - include_dirs = [ ".", "../src" ], - libraries = [ "protobuf" ], - library_dirs = [ '../src/.libs' ], - )) + ext_module_list.append( + Extension( + "google.protobuf.pyext._message", + [ + "google/protobuf/pyext/descriptor.cc", + "google/protobuf/pyext/descriptor_containers.cc", + "google/protobuf/pyext/descriptor_pool.cc", + "google/protobuf/pyext/extension_dict.cc", + "google/protobuf/pyext/message.cc", + "google/protobuf/pyext/repeated_composite_container.cc", + "google/protobuf/pyext/repeated_scalar_container.cc", + ], + define_macros=[('GOOGLE_PROTOBUF_HAS_ONEOF', '1')], + include_dirs=[".", "../src"], + libraries=['protobuf'], + library_dirs=['../src/.libs'], + ) + ) os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'cpp' - setup(name = 'protobuf', - version = GetVersion(), - packages = [ 'google' ], - namespace_packages = [ 'google' ], - test_suite = 'google.protobuf.internal', - # Must list modules explicitly so that we don't install tests. - py_modules = [ - 'google.protobuf.internal.api_implementation', - 'google.protobuf.internal.containers', - 'google.protobuf.internal.decoder', - 'google.protobuf.internal.encoder', - 'google.protobuf.internal.enum_type_wrapper', - 'google.protobuf.internal.message_listener', - 'google.protobuf.internal.python_message', - 'google.protobuf.internal.type_checkers', - 'google.protobuf.internal.wire_format', - 'google.protobuf.descriptor', - 'google.protobuf.descriptor_pb2', - 'google.protobuf.compiler.plugin_pb2', - 'google.protobuf.message', - 'google.protobuf.descriptor_database', - 'google.protobuf.descriptor_pool', - 'google.protobuf.message_factory', - 'google.protobuf.proto_builder', - 'google.protobuf.pyext.cpp_message', - 'google.protobuf.reflection', - 'google.protobuf.service', - 'google.protobuf.service_reflection', - 'google.protobuf.symbol_database', - 'google.protobuf.text_encoding', - 'google.protobuf.text_format'], - cmdclass = { 'clean': clean, 'build_py': build_py }, - install_requires = ['setuptools'], - ext_modules = ext_module_list, - url = 'https://developers.google.com/protocol-buffers/', - maintainer = maintainer_email, - maintainer_email = 'protobuf@googlegroups.com', - license = 'New BSD License', - description = 'Protocol Buffers', - long_description = - "Protocol Buffers are Google's data interchange format.", - ) + setup( + name='protobuf', + version=GetVersion(), + description='Protocol Buffers', + long_description="Protocol Buffers are Google's data interchange format", + url='https://developers.google.com/protocol-buffers/', + maintainer='protobuf@googlegroups.com', + maintainer_email='protobuf@googlegroups.com', + license='New BSD License', + classifiers=[ + 'Programming Language :: Python :: 2.7', + ], + namespace_packages=['google'], + packages=find_packages( + exclude=[ + 'import_test_package', + ], + ), + test_suite='google.protobuf.internal', + cmdclass={ + 'clean': clean, + 'build_py': build_py, + }, + install_requires=['setuptools'], + ext_modules=ext_module_list, + )