Пример #1
0
def generate_file_descriptor(dest_dir, file_descriptor, force_overwrite):
    """Generate a single file descriptor to destination directory.

  Will generate a single Python file from a file descriptor under dest_dir.
  The sub-directory where the file is generated is determined by the package
  name of descriptor.

  Descriptors without package names will not be generated.

  Descriptors that are part of the ProtoRPC distribution will not be generated.

  Args:
    dest_dir: Directory under which to generate files.
    file_descriptor: FileDescriptor instance to generate source code from.
    force_overwrite: If True, existing files will be overwritten.
  """
    package = file_descriptor.package
    if not package:
        # TODO(rafek): Option to cause an error on this condition.
        logging.warn('Will not generate descriptor without package name')
        return

    if package in EXCLUDED_PACKAGES:
        logging.warn('Will not generate main ProtoRPC class %s' % package)
        return

    package_path = package.split('.')
    directory = package_path[:-1]
    package_file_name = package_path[-1]
    directory_name = os.path.join(dest_dir, *directory)
    output_file_name = os.path.join(directory_name,
                                    '%s.py' % (package_file_name, ))

    try:
        os.makedirs(directory_name)
    except OSError as err:
        if err.errno != errno.EEXIST:
            raise

    if not force_overwrite and os.path.exists(output_file_name):
        logging.warn('Not overwriting %s with package %s', output_file_name,
                     package)
        return

    output_file = open(output_file_name, 'w')

    logging.info('Writing package %s to %s', file_descriptor.package,
                 output_file_name)
    generate_python.format_python_file(file_descriptor, output_file)
Пример #2
0
def file_command(options, input_filename=None, output_filename=None):
  """Generate a single descriptor file to Python.

  Args:
    options: Parsed command line options.
    input_filename: File to read protobuf FileDescriptor from.  If None
      will read from stdin.
    output_filename: File to write Python source code to.  If None will
      generate to stdout.
  """
  with open_input_file(input_filename) as input_file:
    descriptor_content = input_file.read()

  if output_filename:
    output_file = open(output_filename, 'w')
  else:
    output_file = sys.stdout

  file_descriptor = protobuf.decode_message(descriptor.FileDescriptor,
                                            descriptor_content)
  generate_python.format_python_file(file_descriptor, output_file)
Пример #3
0
def file_command(options, input_filename=None, output_filename=None):
    """Generate a single descriptor file to Python.

  Args:
    options: Parsed command line options.
    input_filename: File to read protobuf FileDescriptor from.  If None
      will read from stdin.
    output_filename: File to write Python source code to.  If None will
      generate to stdout.
  """
    with open_input_file(input_filename) as input_file:
        descriptor_content = input_file.read()

    if output_filename:
        output_file = open(output_filename, 'w')
    else:
        output_file = sys.stdout

    file_descriptor = protobuf.decode_message(descriptor.FileDescriptor,
                                              descriptor_content)
    generate_python.format_python_file(file_descriptor, output_file)
Пример #4
0
    def DoPythonTest(self, file_descriptor):
        """Execute python test based on a FileDescriptor object.

    The full test of the Python code generation is to generate a Python source
    code file, import the module and regenerate the FileDescriptor from it.
    If the generated FileDescriptor is the same as the original, it means that
    the generated source code correctly implements the actual FileDescriptor.
    """
        file_name = os.path.join(
            self.temp_dir, '%s.py' % (file_descriptor.package or 'blank', ))
        source_file = open(file_name, 'wt')
        try:
            generate_python.format_python_file(file_descriptor, source_file)
        finally:
            source_file.close()

        module_to_import = file_descriptor.package or 'blank'
        module = __import__(module_to_import)

        if not file_descriptor.package:
            self.assertFalse(hasattr(module, 'package'))
            module.package = ''  # Create package name so that comparison will work.

        reloaded_descriptor = descriptor.describe_file(module)

        # Need to sort both message_types fields because document order is never
        # Ensured.
        # TODO(rafek): Ensure document order.
        if reloaded_descriptor.message_types:
            reloaded_descriptor.message_types = sorted(
                reloaded_descriptor.message_types, key=lambda v: v.name)

        if file_descriptor.message_types:
            file_descriptor.message_types = sorted(
                file_descriptor.message_types, key=lambda v: v.name)

        self.assertEquals(file_descriptor, reloaded_descriptor)
  def DoPythonTest(self, file_descriptor):
    """Execute python test based on a FileDescriptor object.

    The full test of the Python code generation is to generate a Python source
    code file, import the module and regenerate the FileDescriptor from it.
    If the generated FileDescriptor is the same as the original, it means that
    the generated source code correctly implements the actual FileDescriptor.
    """
    file_name = os.path.join(self.temp_dir,
                             '%s.py' % (file_descriptor.package or 'blank',))
    source_file = open(file_name, 'wt')
    try:
      generate_python.format_python_file(file_descriptor, source_file)
    finally:
      source_file.close()

    module_to_import = file_descriptor.package or 'blank'
    module = __import__(module_to_import)

    if not file_descriptor.package:
      self.assertFalse(hasattr(module, 'package'))
      module.package = ''  # Create package name so that comparison will work.

    reloaded_descriptor = descriptor.describe_file(module)

    # Need to sort both message_types fields because document order is never
    # Ensured.
    # TODO(rafek): Ensure document order.
    if reloaded_descriptor.message_types:
      reloaded_descriptor.message_types = sorted(
        reloaded_descriptor.message_types, key=lambda v: v.name)

    if file_descriptor.message_types:
      file_descriptor.message_types = sorted(
        file_descriptor.message_types, key=lambda v: v.name)

    self.assertEquals(file_descriptor, reloaded_descriptor)
Пример #6
0
  try:
    os.makedirs(directory_name)
  except OSError, err:
    if err.errno != errno.EEXIST:
      raise

  if not force_overwrite and os.path.exists(output_file_name):
    logging.warn('Not overwriting %s with package %s',
                 output_file_name, package)
    return

  output_file = open(output_file_name, 'w')

  logging.info('Writing package %s to %s',
               file_descriptor.package, output_file_name)
  generate_python.format_python_file(file_descriptor, output_file)


@util.positional(1)
def command(name, required=(), optional=()):
  """Decorator used for declaring commands used on command line.

  Each command of this tool can have any number of sequential required
  parameters and optional parameters.  The required and optional parameters
  will be displayed in the command usage.  Arguments passed in to the command
  are checked to ensure they have at least the required parameters and not
  too many parameters beyond the optional ones.  When there are not enough
  or too few parameters the usage message is generated and the program exits
  with an error code.

  Functions decorated thus are added to commands by their name.
Пример #7
0
    directory_name = os.path.join(dest_dir, *directory)
    output_file_name = os.path.join(directory_name,
                                    '%s.py' % (package_file_name, ))

    try:
        os.makedirs(directory_name)
    except OSError, err:
        if err.errno != errno.EEXIST:
            raise

    output_file = open(output_file_name, 'w')

    logging.info('Writing package %s to %s', file_descriptor.package,
                 output_file_name)
    # TODO(rafek): Option to prevent overwriting.
    generate_python.format_python_file(file_descriptor, output_file)


@util.positional(1)
def command(name, required=(), optional=()):
    """Decorator used for declaring commands used on command line.

  Each command of this tool can have any number of sequential required
  parameters and optional parameters.  The required and optional parameters
  will be displayed in the command usage.  Arguments passed in to the command
  are checked to ensure they have at least the required parameters and not
  too many parameters beyond the optional ones.  When there are not enough
  or too few parameters the usage message is generated and the program exits
  with an error code.

  Functions decorated thus are added to commands by their name.