Python attr.s() Examples

The following are 30 code examples of attr.s(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module attr , or try the search function .
Example #1
Source File: recipe_deps.py    From recipes-py with Apache License 2.0 6 votes vote down vote up
def gen_tests(self):
    """Runs this recipe's GenTests function.

    Yields all TestData fixtures for this recipe. Fills in the .expect_file
    property on each with an absolute path to the expectation file.
    """
    api = RecipeTestApi(module=None)
    resolved_deps = _resolve(
      self.repo.recipe_deps, self.normalized_DEPS, 'TEST_API', None, None)
    api.__dict__.update({
      local_name: resolved_dep
      for local_name, resolved_dep in resolved_deps.iteritems()
      if resolved_dep is not None
    })
    for test_data in self.global_symbols['GenTests'](api):
      test_data.expect_file = os.path.join(
          self.expectation_dir, filesystem_safe(test_data.name),
      ) + '.json'
      yield test_data 
Example #2
Source File: chute.py    From Paradrop with Apache License 2.0 6 votes vote down vote up
def get_default_service(self):
        """
        Get one of the chute's services designated as the default one.

        This is more for convenience with existing API functions where the
        caller did not need to specify a service because prior to 0.12.0,
        chutes could only have one Docker container. We use some heuristics
        such as the service's name is "main" to identify one of the services as
        the default.
        """
        if "main" in self.services:
            return self.services['main']

        # Sort by name and return the first one.
        name = min(self.services)
        return self.services[name] 
Example #3
Source File: test_api.py    From recipes-py with Apache License 2.0 6 votes vote down vote up
def mock_get_swarm(self, job_def, task_id=None):
    """Mocks the initial job.Definition for the given `led get-swarm` call.

    Args:
      * job_def (job.Definition|None) - The initial job value. If `None`, then
        this marks the builder as non-existant, and the `led get-builder` call
        will be simulated to have an exit code of 1.
      * task_id (str|None) - The swarming task ID for the build or None to
        provide the default basis for all get-swarm calls.

    Returns TestData which can be added to a recipe test case.
    """
    assert isinstance(job_def, (job.Definition, type(None)))
    ret = None
    if job_def is not None:
      ret = job.Definition()
      ret.CopyFrom(job_def)
    key = 'get:swarming/task'
    if task_id:
      key += '/%s' % (task_id,)
    return self._singleton_mod_data(key, ret) 
Example #4
Source File: test_api.py    From recipes-py with Apache License 2.0 6 votes vote down vote up
def _derive_build_ids(build):
    """Because users can set any fields on `build`, it may have multiple IDs."""
    ret = set()

    if build.swarming.task.task_id:
      ret.add('swarming/' + build.swarming.task.task_id)

    if build.buildbucket.bbagent_args.build.id:
      ret.add('buildbucket/build/%s'
              % (build.buildbucket.bbagent_args.build.id,))

    if build.buildbucket.bbagent_args.build.builder.bucket:
      ret.add('buildbucket/builder/%s/%s/%s' % (
        build.buildbucket.bbagent_args.build.builder.project,
        build.buildbucket.bbagent_args.build.builder.bucket,
        build.buildbucket.bbagent_args.build.builder.builder))

    return ret 
Example #5
Source File: check_tap.py    From singer-tools with Apache License 2.0 6 votes vote down vote up
def print_summary(summary):

    print('The output is valid.')
    print('It contained {} messages for {} streams.'.format(
        summary.num_messages(), len(summary.streams)))
    print('')
    print('{:7} schema messages'.format(summary.num_schemas()))
    print('{:7} record messages'.format(summary.num_records()))
    print('{:7} state messages'.format(summary.num_states))
    print('')
    print('Details by stream:')
    headers = [['stream', 'records', 'schemas']]
    rows = [[s.name, s.num_records, s.num_schemas]
            for s in summary.streams.values()]
    data = headers + rows

    table = AsciiTable(data)
    print(table.table) 
Example #6
Source File: api.py    From recipes-py with Apache License 2.0 6 votes vote down vote up
def make_channel(self):
    """Returns a single-slot communication device for passing data and control
    between concurrent functions.

    This is useful for running 'background helper' type concurrent processes.

    NOTE: It is strongly discouraged to pass Channel objects outside of a recipe
    module. Access to the channel should be mediated via
    a class/contextmanager/function which you return to the caller, and the
    caller can call in a makes-sense-for-your-moudle's-API way.

    See ./tests/background_helper.py for an example of how to use a Channel
    correctly.

    It is VERY RARE to need to use a Channel. You should avoid using this unless
    you carefully consider and avoid the possibility of introducing deadlocks.

    Channels will raise ValueError if used with @@@annotation@@@ mode.
    """
    if not self.concurrency_client.supports_concurrency: # pragma: no cover
      # test mode always supports concurrency, hence the nocover
      raise ValueError('Channels are not allowed in @@@annotation@@@ mode')
    return gevent.queue.Channel() 
Example #7
Source File: report.py    From recipes-py with Apache License 2.0 6 votes vote down vote up
def _print_summary_info(verbose, use_emoji, test_name, test_result,
                        space_for_columns):
  # Pick the first populated field in the TestResults.Results
  for field_name in FIELD_TO_DISPLAY:
    (success, verbose_msg, emj, txt), _ = _check_field(test_result, field_name)
    icon = emj if use_emoji else txt
    if icon:
      break

  if verbose:
    msg = '' if not verbose_msg else ' (%s)' % verbose_msg
    print '%s ... %s%s' % (test_name, 'ok' if success else 'FAIL', msg)
  else:
    space_for_columns(1 if len(icon) == 1 else 2)
    sys.stdout.write(icon)
  sys.stdout.flush() 
Example #8
Source File: __init__.py    From recipes-py with Apache License 2.0 6 votes vote down vote up
def register_step_config(self, name_token, step_config):
    """Called to register the precursor of the step (the StepConfig).

    Only used for the simulation API.

    TODO(iannucci): Change all step expectations to instead reflect the engine's
    intent (i.e. the Step object passed to `run`). Currently this is used to
    provide env_prefixes, env_suffixes as distinct from env. However, it may be
    "just fine" to instead only record env in the test expectations (i.e. using
    FakeEnviron as a basis environment).

    Args:
      * name_tokens (List[str]) - The full name of the step.
      * step_config (StepConfig) - The full precursor of the step.
    """
    pass 
Example #9
Source File: __init__.py    From recipes-py with Apache License 2.0 6 votes vote down vote up
def placeholder(self, name_tokens, placeholder):
    """Returns PlaceholderTestData for the given step and placeholder
    combination.

    Note: This may be called multiple times for the same step/placeholder
    combination. It should always return the same test data.

    Args:

      * name_tokens (List[str]) - The full name of the step.
      * placeholder (Placeholder) - The actual placeholder to resolve for.
        This may inspect the placeholder's namespaces and/or name.

    Returns PlaceholderTestData (or BaseTestData with enabled=False).
    """
    return BaseTestData(False) 
Example #10
Source File: __init__.py    From recipes-py with Apache License 2.0 6 votes vote down vote up
def resolve_cmd0(self, name_tokens, debug_log, cmd0, cwd, paths):
    """Should resolve the 0th argument of the command (`cmd0`) to an absolute
    path to the intended executable.

    Args:
      * name_tokens (List[str]) - The full name of the step.
      * debug_log (Stream) - The log where debugging information about the
        StepRunner's thought process should go.
      * cmd0 (str) - The executable to resolve. Note that this may be a relative
        path (e.g. './foo').
      * cwd (str) - The absolute cwd for the step.
      * paths (List[str]) - The current split value of $PATH.

    Returns the absolute path to the intended executable, if found, or None if
    it couldn't be discovered.
    """
    return cmd0 
Example #11
Source File: __init__.py    From recipes-py with Apache License 2.0 6 votes vote down vote up
def run_noop(self, name_tokens, debug_log):
    """Runs a no-op step.

    This may occur becuase the recipe needs to establish some step for UI
    purposes, but is also used for some recipes which run test steps without
    actual content (and so the simulations need an API point to return mocked
    ExecutionResult data).

    Args:
      * name_tokens (List[str]) - The full name of the step.
      * debug_log (Stream) - The log where debugging information about the
        StepRunner's thought process should go.

    Returns recipe_engine.step_data.ExecutionResult.
    """
    return ExecutionResult(retcode=0) 
Example #12
Source File: sim.py    From recipes-py with Apache License 2.0 6 votes vote down vote up
def export_steps_ran(self):
    """Returns a dictionary of all steps run.

    This maps from the step's dot-name to dictionaries of:

      * name (str) - The step's dot-name
      * cmd (List[str]) - The command
      * cwd (str) - The current working directory
      * env (Dict[str, (str|None)]) - Mapping of direct environment
        replacements.
      * env_prefixes (Dict[str, List[str]]) - Mapping of direct environment
        replacements which should be joined at the beginning of the env key with
        os.pathsep.
      * env_suffixes (Dict[str, List[str]]) - Mapping of direct environment
        replacements which should be joined at the end of the env key with
        os.pathsep.
      * infra_step (bool) - If this step was intended to be an 'infra step' or
        not.
      * timeout (int) - The timeout, in seconds.

    TODO(iannucci): Make this map to a real type.
    """
    return self._step_history.copy() 
Example #13
Source File: post_process_inputs.py    From recipes-py with Apache License 2.0 6 votes vote down vote up
def from_step_dict(cls, step_dict):
    """Create a `Step` from a step dictionary.

    Args:
      * step_dict - Dictionary containing the data to be written out to the
          expectation file for the step. All keys in the dictionary must match
          the name of one of the fields of `Step`.

    Returns:
      A `Step` object where for each item in `step_dict`, the field whose name
      matches the item's key is set to the item's value.
    """
    if 'name' not in step_dict:
      raise ValueError("step dict must have 'name' key, step dict keys: %r"
                       % sorted(step_dict.iterkeys()))
    if 'cmd' in step_dict or 'cost' in step_dict:
      step_dict = step_dict.copy()
      if 'cmd' in step_dict:
        step_dict['cmd'] = Command(step_dict['cmd'])
      if 'cost' in step_dict and step_dict['cost'] is not None:
        step_dict['cost'] = ResourceCost(**step_dict['cost'])
    return cls(**step_dict) 
Example #14
Source File: luci.py    From recipes-py with Apache License 2.0 6 votes vote down vote up
def render(self):
    escape_parens = lambda link: link.replace('(', r'\(').replace(')', r'\)')

    paragraphs = []

    if self._step_summary_text:
      paragraphs.append(self._step_summary_text)

    if self._step_text:
      paragraphs.append(self._step_text)

    if self._step_links:
      paragraphs.append(
          '\n'.join(
              '  * [%s](%s)' % (name, escape_parens(link))
              for name, link in self._step_links))

    return '\n\n'.join(paragraphs) 
Example #15
Source File: record.py    From recipes-py with Apache License 2.0 6 votes vote down vote up
def record_import_warning(self, name, importer):
    """Record the warning issued during DEPS resolution and its cause (
    warning_pb.ImportSite).

    Args:
      * name (str): Fully qualified warning name (e.g. repo_name/WARNING_NAME)
      * importer (Recipe|RecipeModule): The recipe or recipe module which
      depends on a recipe module with given warning name declared

    Raise ValueError if the importer is not instance of Recipe or RecipeModule
    """
    if not isinstance(importer, (Recipe, RecipeModule)):
      raise ValueError(
        "Expect importer to be either type %s or %s. Got %s" % (
          RecipeModule.__name__, Recipe.__name__, type(importer)))
    import_site = ImportSite(
      repo=importer.repo.name,
      module=importer.name if isinstance(importer, RecipeModule) else None,
      recipe=importer.name if isinstance(importer, Recipe) else None,
    )
    if (import_site not in self._recorded_warnings[name]) and (
        self.import_site_filter(name, import_site.cause_pb)):
        self._recorded_warnings[name].add(import_site) 
Example #16
Source File: escape.py    From recipes-py with Apache License 2.0 5 votes vote down vote up
def escape_warnings(*warning_name_regexps):
  """A function decorator which will cause warnings matching any of the given
  regexps to be attributed to the decorated function's caller instead of the
  decorated function itself.
  """
  def _escape_warnings(func):
    func_loc = _FuncLoc.from_code_obj(func.__code__)
    WARNING_ESCAPE_REGISTRY[func_loc] = (
      tuple(re.compile(r) for r in warning_name_regexps))
    return func
  return _escape_warnings 
Example #17
Source File: cause.py    From recipes-py with Apache License 2.0 5 votes vote down vote up
def __attrs_post_init__(self):
    """Check that exactly one of recipe or recipe module is present"""
    if bool(self.module) == bool(self.recipe):
      raise ValueError(
        'Expect exactly one of recipe or recipe module presents. '
        'Got module:%s, recipe:%s' % (self.module, self.recipe)) 
Example #18
Source File: recipe_deps.py    From recipes-py with Apache License 2.0 5 votes vote down vote up
def full_name(self):
    """The fully qualified name of the recipe (e.g. `repo::path/to/recipe`, or
    `repo::module:run/recipe`)."""
    return '%s::%s' % (self.repo.name, self.name) 
Example #19
Source File: recipe_deps.py    From recipes-py with Apache License 2.0 5 votes vote down vote up
def resources_dir(self):
    """Returns the directory where this recipe's resource files live."""
    return os.path.splitext(self.path)[0] + '.resources' 
Example #20
Source File: recipe_deps.py    From recipes-py with Apache License 2.0 5 votes vote down vote up
def create(cls, repo, name):
    """Creates a RecipeModule.

    Args:
      * repo (RecipeRepo) - The recipe repo to which this module belongs.
      * name (str) - The name of this recipe module.

    Returns a RecipeModule.
    """
    # A bit hacky; Recipe objects have a backreference to the module, so we
    # have to create it first.
    ret = cls(repo, name, {})

    recipes = {}

    for subdir_name in ('tests', 'examples', 'run'):
      subdir = os.path.join(ret.path, subdir_name)
      if os.path.isdir(subdir):
        for recipe_name in _scan_recipe_directory(subdir):
          mod_scoped_name = '%s/%s' % (subdir_name, recipe_name)
          recipes[mod_scoped_name] = Recipe(
            repo,
            '%s:%s' % (name, mod_scoped_name),
            ret)

    # This makes `recipes` unmodifiable. object.__setattr__ is needed to get
    # around attrs' frozen attributes.
    recipes = freeze(recipes)
    recipes.on_missing = ret.recipes.on_missing
    object.__setattr__(ret, 'recipes', recipes)

    return ret 
Example #21
Source File: __init__.py    From recipes-py with Apache License 2.0 5 votes vote down vote up
def run(self, name_tokens, debug_log, step):
    """Runs the step defined by step_config.

    Args:
      * name_tokens (List[str]) - The full name of the step.
      * debug_log (Stream) - The log where debugging information about the
        StepRunner's thought process should go.
      * step (Step) - The step to run.

    Returns recipe_engine.step_data.ExecutionResult.
    """
    raise NotImplementedError() 
Example #22
Source File: simple_cfg.py    From recipes-py with Apache License 2.0 5 votes vote down vote up
def from_json_file(cls, path):
    """Parses a SimpleRecipesCfg from a file on disk.

    Args:
      * path (str) - The path to the file to parse (this path is not retained
        so it's absolutness doesn't matter).

    Returns SimpleRecipesCfg
    """
    try:
      with open(path, 'r') as fil:
        data = fil.read()
    except OSError as ex:
      raise ValueError('Error opening recipes.cfg: %s' % (ex,))
    return cls.from_json_string(data) 
Example #23
Source File: engine.py    From recipes-py with Apache License 2.0 5 votes vote down vote up
def _setup_build_step(self, recipe, emit_initial_properties):
    with self._stream_engine.new_step_stream(('setup_build',), False) as step:
      step.mark_running()
      if emit_initial_properties:
        for key in sorted(self.properties.iterkeys()):
          step.set_build_property(
              key, json.dumps(self.properties[key], sort_keys=True))

      run_recipe_help_lines = [
          'To repro this locally, run the following line from the root of a %r'
            ' checkout:' % (self._recipe_deps.main_repo.name),
          '',
          '%s run --properties-file - %s <<EOF' % (
              os.path.join(
                  '.', self._recipe_deps.main_repo.simple_cfg.recipes_path,
                  'recipes.py'),
              recipe),
      ]
      run_recipe_help_lines.extend(
          json.dumps(self.properties, indent=2).splitlines())
      run_recipe_help_lines += [
          'EOF',
          '',
          'To run on Windows, you can put the JSON in a file and redirect the',
          'contents of the file into run_recipe.py, with the < operator.',
      ]

      with step.new_log_stream('run_recipe') as log:
        for line in run_recipe_help_lines:
          log.write_line(line)

      with step.new_log_stream('memory_profile') as memory_log:
        self._write_memory_snapshot(memory_log, 'Step: setup_build')

      step.write_line('Running recipe with %s' % (self.properties,))
      step.add_step_text('running recipe: "%s"' % recipe) 
Example #24
Source File: engine.py    From recipes-py with Apache License 2.0 5 votes vote down vote up
def close_non_parent_step(self):
    """Closes the tip of the _step_stack if it's not a parent nesting step."""
    try:
      tip_step = self._step_stack[-1]
      if tip_step.is_parent:
        return

      self._step_stack.pop().close()
    except:
      _log_crash(self._stream_engine, "close_non_parent_step()")
      raise CrashEngine("Closing non-parent step failed.") 
Example #25
Source File: engine.py    From recipes-py with Apache License 2.0 5 votes vote down vote up
def initialize_path_client_HACK(self, root_api):
    """This is a hack; the "PathsClient" currently works to provide a reverse
    string->Path lookup by walking down the recipe's `api` object and calling
    the various 'root' path methods (like .resource(), etc.).

    However, we would like to eventually simplify the 'paths' system, whose
    whole complexity exists to facilitate 'pure-data' config.py processing,
    which is also going to be deprecated in favor of protos and removal of the
    config subsystem.

    Args:
      * root_api (RecipeScriptApi): The root `api` object which would be passed
        to the recipe's RunSteps function.
    """
    self._clients['paths']._initialize_with_recipe_api(root_api) 
Example #26
Source File: engine.py    From recipes-py with Apache License 2.0 5 votes vote down vote up
def resolve_requirement(self, req):
    """Resolves a requirement or raises ValueError if it cannot be resolved.

    Args:
      * req (_UnresolvedRequirement): The requirement to resolve.

    Returns the resolved requirement.
    Raises ValueError if the requirement cannot be satisfied.
    """
    # pylint: disable=protected-access
    assert isinstance(req, recipe_api._UnresolvedRequirement)
    if req._typ == 'client':
      return self._clients.get(req._name)
    raise ValueError('Unknown requirement type [%s]' % (req._typ,)) 
Example #27
Source File: engine.py    From recipes-py with Apache License 2.0 5 votes vote down vote up
def snapshot(self, snapshot_name):
    """ Snapshot the memory

    Returns [geneorator of str] - formated memory snapshot or diff surrounded by
    dividing line. When this method is called for the first time, the full
    snapshot will be returned. After that,  it will only return the diff with
    the previous snapshot.
    """
    sum = self._tracker.create_summary()
    last_snapshot_name = self._current_snapshot_name
    self._current_snapshot_name = snapshot_name
    if self._diff_snapshot:
      yield ((
        '-------- Diff between current snapshot (%s) and last snapshot (%s) '
        'Starts --------') % (snapshot_name, last_snapshot_name))
      diff = self._tracker.diff(summary1=sum)
      # TODO(yiwzhang): switch to yield from after moving to python 3
      for diff_line in summary.format_(diff):
        yield diff_line
      yield ((
        '-------- Diff between current snapshot (%s) and last snapshot (%s) '
        'Ends --------') % (snapshot_name, last_snapshot_name))
    else:
      # create_summary() won't make the return value latest summary in the
      # underlying tracker. Manually moving it forward
      self._tracker.s0 = sum
      # Only dump the full snapshot when this method is called for the first
      # time. From then onwards, dump diff only
      self._diff_snapshot = True
      yield '-------- Memory Snapshot (%s) Start --------' % snapshot_name
      # TODO(yiwzhang): switch to yield from after moving to python 3
      for snapshot_line in summary.format_(sum):
        yield snapshot_line
      yield '-------- Memory Snapshot (%s) Ends --------' % snapshot_name 
Example #28
Source File: report.py    From recipes-py with Apache License 2.0 5 votes vote down vote up
def _print_detail_info(err_buf, test_name, test_result):
  verbose_msg = None

  def _header():
    print >>err_buf, '=' * 70
    print >>err_buf, 'FAIL (%s) - %s' % (verbose_msg, test_name)
    print >>err_buf, '-' * 70

  for field in ('internal_error', 'bad_test', 'crash_mismatch'):
    (_, verbose_msg, _, _), lines = _check_field(test_result, field)
    if lines:
      _header()
      for line in lines:
        print >>err_buf, line
      print >>err_buf

  (_, verbose_msg, _, _), lines_groups = _check_field(test_result, 'check')
  if lines_groups:
    _header()
    for group in lines_groups:
      for line in group.lines:
        print >>err_buf, line
      print >>err_buf

  (_, verbose_msg, _, _), lines = _check_field(test_result, 'diff')
  if lines:
    _header()
    for line in lines.lines:
      print >>err_buf, line
    print >>err_buf 
Example #29
Source File: report.py    From recipes-py with Apache License 2.0 5 votes vote down vote up
def short_report(self, outcome_msg):
    """Prints all test results from `outcome_msg` to stdout.

    Detailed error messages (if any) will be accumulated in this reporter.

    NOTE: Will report and then raise SystemExit if the outcome_msg contains an
    'internal_error', as this indicates that the test harness is in an invalid
    state.

    Args:

      * outcome_msg (Outcome proto) - The message to report.

    Raises SystemExit if outcome_msg has an internal_error.
    """
    # Global error; this means something in the actual test execution code went
    # wrong.
    if outcome_msg.internal_error:
      # This is pretty bad.
      print 'ABORT ABORT ABORT'
      print 'Global failure(s):'
      for failure in outcome_msg.internal_error:
        print '  ', failure
      sys.exit(1)

    has_fail = False
    for test_name, test_result in outcome_msg.test_results.iteritems():
      _print_summary_info(
          self._verbose, self._use_emoji, test_name, test_result,
          self._space_for_columns)
      _print_detail_info(self._long_err_buf, test_name, test_result)

      has_fail = self._fail_tracker.cache_recent_fails(test_name,
                                                       test_result) or has_fail

    return has_fail 
Example #30
Source File: master.py    From tfont with Apache License 2.0 5 votes vote down vote up
def __repr__(self):
        more = ""
        font = self._parent
        if font is not None:
            loc = self.location
            axes = font.axes
            for tag in ("wght", "wdth"):
                try:
                    more += ", %s=%r" % (tag, loc.get(tag, axes[tag]))
                except KeyError:
                    pass
        return "%s(%r%s)" % (self.__class__.__name__, self.name, more)