def test_standard_values(self):
        o = OptionValueContainer()
        o.foo = 1
        self.assertEqual(1, o.foo)

        with self.assertRaises(AttributeError):
            o.bar
Example #2
0
    def for_scope(self, scope):
        """Return the option values for the given scope.

    Values are attributes of the returned object, e.g., options.foo.
    Computed lazily per scope.
    """
        # Short-circuit, if already computed.
        if scope in self._values_by_scope:
            return self._values_by_scope[scope]

        # First get enclosing scope's option values, if any.
        if scope == GLOBAL_SCOPE:
            values = OptionValueContainer()
            if self._legacy_values:
                values.update(vars(
                    self._legacy_values))  # Proxy any legacy option values.
        else:
            values = copy.copy(self.for_scope(scope.rpartition('.')[0]))

        # Now add our values.
        try:
            flags_in_scope = self._scope_to_flags.get(scope, [])
            self._parser_hierarchy.get_parser_by_scope(scope).parse_args(
                flags_in_scope, values)
            self._values_by_scope[scope] = values
            return values
        except ParseError as e:
            self.print_help(str(e))
            sys.exit(1)
Example #3
0
    def test_unknown_values(self) -> None:
        o = OptionValueContainer()
        o.foo = RankedValue(RankedValue.HARDCODED, 1)
        self.assertEqual(1, o.foo)

        with self.assertRaises(AttributeError):
            o.bar
Example #4
0
 def test_iterator(self) -> None:
     o = OptionValueContainer()
     o.a = RankedValue(RankedValue.FLAG, 3)
     o.b = RankedValue(RankedValue.FLAG, 2)
     o.c = RankedValue(RankedValue.FLAG, 1)
     names = list(iter(o))
     self.assertListEqual(["a", "b", "c"], names)
Example #5
0
  def for_scope(self, scope):
    """Return the option values for the given scope.

    Values are attributes of the returned object, e.g., options.foo.
    Computed lazily per scope.
    """
    # Short-circuit, if already computed.
    if scope in self._values_by_scope:
      return self._values_by_scope[scope]

    # First get enclosing scope's option values, if any.
    if scope == GLOBAL_SCOPE:
      values = OptionValueContainer()
      if self._legacy_values:
        values.update(vars(self._legacy_values))  # Proxy any legacy option values.
    else:
      values = copy.copy(self.for_scope(scope.rpartition('.')[0]))

    # Now add our values.
    try:
      flags_in_scope = self._scope_to_flags.get(scope, [])
      self._parser_hierarchy.get_parser_by_scope(scope).parse_args(flags_in_scope, values)
      self._values_by_scope[scope] = values
      return values
    except ParseError as e:
      self.print_help(str(e))
      sys.exit(1)
  def test_standard_values(self):
    o = OptionValueContainer()
    o.foo = 1
    self.assertEqual(1, o.foo)

    with self.assertRaises(AttributeError):
      o.bar
 def test_iterator(self):
     o = OptionValueContainer()
     o.a = 3
     o.b = 2
     o.c = 1
     names = list(iter(o))
     self.assertListEqual(['a', 'b', 'c'], names)
  def test_unknown_values(self):
    o = OptionValueContainer()
    o.foo = RankedValue(RankedValue.HARDCODED, 1)
    self.assertEqual(1, o.foo)

    with self.assertRaises(AttributeError):
      o.bar
 def test_iterator(self):
   o = OptionValueContainer()
   o.a = 3
   o.b = 2
   o.c = 1
   names = list(iter(o))
   self.assertListEqual(['a', 'b', 'c'], names)
Example #10
0
    def for_scope(self, scope):
        """Return the option values for the given scope.

    Values are attributes of the returned object, e.g., options.foo.
    Computed lazily per scope.

    :API: public
    """
        # Short-circuit, if already computed.
        if scope in self._values_by_scope:
            return self._values_by_scope[scope]

        # First get enclosing scope's option values, if any.
        if scope == GLOBAL_SCOPE:
            values = OptionValueContainer()
        else:
            values = copy.copy(self.for_scope(enclosing_scope(scope)))

        # Now add our values.
        flags_in_scope = self._scope_to_flags.get(scope, [])
        self._parser_hierarchy.get_parser_by_scope(scope).parse_args(
            flags_in_scope, values)
        self._values_by_scope[scope] = values
        for option in values:
            self._option_tracker.record_option(scope=scope,
                                               option=option,
                                               value=values[option],
                                               rank=values.get_rank(option))
        return values
 def test_iterator(self):
   o = OptionValueContainer()
   o.a = RankedValue(RankedValue.FLAG, 3)
   o.b = RankedValue(RankedValue.FLAG, 2)
   o.c = RankedValue(RankedValue.FLAG, 1)
   names = list(iter(o))
   self.assertListEqual(['a', 'b', 'c'], names)
Example #12
0
 def test_iterator(self):
     o = OptionValueContainer()
     o.a = RankedValue(RankedValue.FLAG, 3)
     o.b = RankedValue(RankedValue.FLAG, 2)
     o.c = RankedValue(RankedValue.FLAG, 1)
     names = list(iter(o))
     self.assertListEqual(['a', 'b', 'c'], names)
Example #13
0
    def for_scope(self, scope):
        """Return the option values for the given scope.

    Values are attributes of the returned object, e.g., options.foo.
    Computed lazily per scope.
    """
        # Short-circuit, if already computed.
        if scope in self._values_by_scope:
            return self._values_by_scope[scope]

        # First get enclosing scope's option values, if any.
        if scope == GLOBAL_SCOPE:
            values = OptionValueContainer()
        else:
            values = copy.deepcopy(self.for_scope(enclosing_scope(scope)))

        # Now add our values.
        flags_in_scope = self._scope_to_flags.get(scope, [])
        self._parser_hierarchy.get_parser_by_scope(scope).parse_args(flags_in_scope, values)
        self._values_by_scope[scope] = values
        for option in values:
            self._option_tracker.record_option(
                scope=scope, option=option, value=values[option], rank=values.get_rank(option)
            )
        return values
Example #14
0
    def for_scope(self, scope, inherit_from_enclosing_scope=True):
        """Return the option values for the given scope.

    Values are attributes of the returned object, e.g., options.foo.
    Computed lazily per scope.

    :API: public
    """
        # Short-circuit, if already computed.
        if scope in self._values_by_scope:
            return self._values_by_scope[scope]

        # First get enclosing scope's option values, if any.
        if scope == GLOBAL_SCOPE or not inherit_from_enclosing_scope:
            values = OptionValueContainer()
        else:
            values = copy.copy(self.for_scope(enclosing_scope(scope)))

        # Now add our values.
        flags_in_scope = self._scope_to_flags.get(scope, [])
        self._parser_hierarchy.get_parser_by_scope(scope).parse_args(
            flags_in_scope, values)

        # If we're the new name of a deprecated scope, also get values from that scope.
        deprecated_scope = self.known_scope_to_info[scope].deprecated_scope
        # Note that deprecated_scope and scope share the same Optionable class, so deprecated_scope's
        # Optionable has a deprecated_options_scope equal to deprecated_scope. Therefore we must
        # check that scope != deprecated_scope to prevent infinite recursion.
        if deprecated_scope is not None and scope != deprecated_scope:
            # Do the deprecation check only on keys that were explicitly set on the deprecated scope
            # (and not on its enclosing scopes).
            explicit_keys = self.for_scope(
                deprecated_scope,
                inherit_from_enclosing_scope=False).get_explicit_keys()
            if explicit_keys:
                warn_or_error(
                    self.known_scope_to_info[scope].
                    deprecated_scope_removal_version,
                    'scope {}'.format(deprecated_scope),
                    'Use scope {} instead (options: {})'.format(
                        scope, ', '.join(explicit_keys)))
                # Update our values with those of the deprecated scope (now including values inherited
                # from its enclosing scope).
                # Note that a deprecated val will take precedence over a val of equal rank.
                # This makes the code a bit neater.
                values.update(self.for_scope(deprecated_scope))

        # Record the value derivation.
        for option in values:
            self._option_tracker.record_option(scope=scope,
                                               option=option,
                                               value=values[option],
                                               rank=values.get_rank(option))

        # Cache the values.
        self._values_by_scope[scope] = values

        return values
Example #15
0
  def test_indexing(self):
    o = OptionValueContainer()
    o.add_forwardings({'foo': 'bar'})
    o.bar = 1
    self.assertEqual(1, o['foo'])
    self.assertEqual(1, o['bar'])

    with self.assertRaises(AttributeError):
      o['baz']
 def test_deepcopy(self):
   # deepcopy semantics can get hairy when overriding __setattr__/__getattr__, so we test them.
   o = OptionValueContainer()
   o.foo = 1
   o.bar = {'a': 111}
   p = copy.deepcopy(o)
   o.bar['b'] = 222  # Add to original dict.
   self.assertEqual(1, p.foo)
   self.assertEqual({'a': 111}, p.bar)  # Ensure dict was copied.
Example #17
0
 def assert_option_resolved(
     *, old_configured: bool = False, new_configured: bool = False, expected: str,
 ) -> None:
     old_container, new_container = OptionValueContainer(), OptionValueContainer()
     old_container.my_opt = old_configured_rv if old_configured else old_default_rv
     new_container.my_opt = new_configured_rv if new_configured else new_default_rv
     assert (
         resolve_options(old_container=old_container, new_container=new_container)
         == expected
     )
Example #18
0
  def for_scope(self, scope, inherit_from_enclosing_scope=True):
    """Return the option values for the given scope.

    Values are attributes of the returned object, e.g., options.foo.
    Computed lazily per scope.

    :API: public
    """
    # Short-circuit, if already computed.
    if scope in self._values_by_scope:
      return self._values_by_scope[scope]

    # First get enclosing scope's option values, if any.
    if scope == GLOBAL_SCOPE or not inherit_from_enclosing_scope:
      values = OptionValueContainer()
    else:
      values = copy.copy(self.for_scope(enclosing_scope(scope)))

    # Now add our values.
    flags_in_scope = self._scope_to_flags.get(scope, [])
    self._parser_hierarchy.get_parser_by_scope(scope).parse_args(flags_in_scope, values)

    # If we're the new name of a deprecated scope, also get values from that scope.
    deprecated_scope = self.known_scope_to_info[scope].deprecated_scope
    # Note that deprecated_scope and scope share the same Optionable class, so deprecated_scope's
    # Optionable has a deprecated_options_scope equal to deprecated_scope. Therefore we must
    # check that scope != deprecated_scope to prevent infinite recursion.
    if deprecated_scope is not None and scope != deprecated_scope:
      # Do the deprecation check only on keys that were explicitly set on the deprecated scope
      # (and not on its enclosing scopes).
      explicit_keys = self.for_scope(deprecated_scope,
                                     inherit_from_enclosing_scope=False).get_explicit_keys()
      if explicit_keys:
        warn_or_error(self.known_scope_to_info[scope].deprecated_scope_removal_version,
                      'scope {}'.format(deprecated_scope),
                      'Use scope {} instead (options: {})'.format(scope, ', '.join(explicit_keys)))
        # Update our values with those of the deprecated scope (now including values inherited
        # from its enclosing scope).
        # Note that a deprecated val will take precedence over a val of equal rank.
        # This makes the code a bit neater.
        values.update(self.for_scope(deprecated_scope))

    # Record the value derivation.
    for option in values:
      self._option_tracker.record_option(scope=scope, option=option, value=values[option],
                                         rank=values.get_rank(option))

    # Cache the values.
    self._values_by_scope[scope] = values

    return values
Example #19
0
    def test_is_flagged(self) -> None:
        o = OptionValueContainer()

        o.foo = RankedValue(RankedValue.NONE, 11)
        self.assertFalse(o.is_flagged("foo"))

        o.foo = RankedValue(RankedValue.CONFIG, 11)
        self.assertFalse(o.is_flagged("foo"))

        o.foo = RankedValue(RankedValue.ENVIRONMENT, 11)
        self.assertFalse(o.is_flagged("foo"))

        o.foo = RankedValue(RankedValue.FLAG, 11)
        self.assertTrue(o.is_flagged("foo"))
Example #20
0
 def test_value_ranking(self) -> None:
     o = OptionValueContainer()
     o.foo = RankedValue(RankedValue.CONFIG, 11)
     self.assertEqual(11, o.foo)
     self.assertEqual(RankedValue.CONFIG, o.get_rank("foo"))
     o.foo = RankedValue(RankedValue.HARDCODED, 22)
     self.assertEqual(11, o.foo)
     self.assertEqual(RankedValue.CONFIG, o.get_rank("foo"))
     o.foo = RankedValue(RankedValue.ENVIRONMENT, 33)
     self.assertEqual(33, o.foo)
     self.assertEqual(RankedValue.ENVIRONMENT, o.get_rank("foo"))
     o.foo = RankedValue(RankedValue.FLAG, 44)
     self.assertEqual(44, o.foo)
     self.assertEqual(RankedValue.FLAG, o.get_rank("foo"))
 def test_value_ranking(self):
     o = OptionValueContainer()
     o.foo = RankedValue(RankedValue.CONFIG, 11)
     self.assertEqual(11, o.foo)
     self.assertEqual(RankedValue.CONFIG, o.get_rank('foo'))
     o.foo = RankedValue(RankedValue.HARDCODED, 22)
     self.assertEqual(11, o.foo)
     self.assertEqual(RankedValue.CONFIG, o.get_rank('foo'))
     o.foo = RankedValue(RankedValue.ENVIRONMENT, 33)
     self.assertEqual(33, o.foo)
     self.assertEqual(RankedValue.ENVIRONMENT, o.get_rank('foo'))
     o.foo = 44  # No explicit rank is assumed to be a FLAG.
     self.assertEqual(44, o.foo)
     self.assertEqual(RankedValue.FLAG, o.get_rank('foo'))
 def test_iterator(self):
     o = OptionValueContainer()
     o.add_forwardings({'a': '_a'})
     o.add_forwardings({'b': '_b'})
     o.add_forwardings({'b_prime': '_b'})  # Should be elided in favor of b.
     o.add_forwardings({'c': '_c'})
     names = list(iter(o))
     self.assertListEqual(['a', 'b', 'c'], names)
  def test_deepcopy(self):
    # copy semantics can get hairy when overriding __setattr__/__getattr__, so we test them.
    o = OptionValueContainer()
    o.foo = RankedValue(RankedValue.FLAG, 1)
    o.bar = RankedValue(RankedValue.FLAG, {'a': 111})

    p = copy.deepcopy(o)

    # Verify that the result is in fact a copy.
    self.assertEqual(1, p.foo)  # Has original attribute.
    o.baz = RankedValue(RankedValue.FLAG, 42)
    self.assertFalse(hasattr(p, 'baz'))  # Does not have attribute added after the copy.

    # Verify that it's a deep copy by modifying a referent in o and reading it in p.
    o.bar['b'] = 222
    self.assertEqual({'a': 111}, p.bar)
Example #24
0
    def for_scope(self, scope, inherit_from_enclosing_scope=True):
        """Return the option values for the given scope.

    Values are attributes of the returned object, e.g., options.foo.
    Computed lazily per scope.

    :API: public
    """
        # Short-circuit, if already computed.
        if scope in self._values_by_scope:
            return self._values_by_scope[scope]

        # First get enclosing scope's option values, if any.
        if scope == GLOBAL_SCOPE or not inherit_from_enclosing_scope:
            values = OptionValueContainer()
        else:
            values = copy.copy(self.for_scope(enclosing_scope(scope)))

        # Now add our values.
        flags_in_scope = self._scope_to_flags.get(scope, [])
        self._parser_hierarchy.get_parser_by_scope(scope).parse_args(
            flags_in_scope, values)

        # Check for any deprecation conditions, which are evaluated using `self._flag_matchers`.
        self._check_deprecations(scope, flags_in_scope, values)

        # Cache the values.
        self._values_by_scope[scope] = values

        return values
    def test_forwarding(self):
        o = OptionValueContainer()
        o.add_forwardings({'foo': 'bar'})
        o.bar = 1
        self.assertEqual(1, o.foo)
        o.bar = 2
        self.assertEqual(2, o.foo)

        o.add_forwardings({'baz': 'qux'})
        o.qux = 3
        self.assertEqual(2, o.foo)
        self.assertEqual(3, o.baz)

        # Direct setting overrides forwarding.
        o.foo = 4
        self.assertEqual(4, o.foo)
Example #26
0
  def for_scope(self, scope, inherit_from_enclosing_scope=True):
    """Return the option values for the given scope.

    Values are attributes of the returned object, e.g., options.foo.
    Computed lazily per scope.

    :API: public
    """

    # First get enclosing scope's option values, if any.
    if scope == GLOBAL_SCOPE or not inherit_from_enclosing_scope:
      values = OptionValueContainer()
    else:
      values = copy.copy(self.for_scope(enclosing_scope(scope)))

    # Now add our values.
    flags_in_scope = self._scope_to_flags.get(scope, [])
    parse_args_request = self._make_parse_args_request(flags_in_scope, values)
    self._parser_hierarchy.get_parser_by_scope(scope).parse_args(parse_args_request)

    # Check for any deprecation conditions, which are evaluated using `self._flag_matchers`.
    if inherit_from_enclosing_scope:
      self._check_and_apply_deprecations(scope, values)

    return values
    def test_indexing(self):
        o = OptionValueContainer()
        o.add_forwardings({'foo': 'bar'})
        o.bar = 1
        self.assertEqual(1, o['foo'])
        self.assertEqual(1, o['bar'])

        self.assertEqual(1, o.get('foo'))
        self.assertEqual(1, o.get('foo', 2))
        self.assertIsNone(o.get('unknown'))
        self.assertEqual(2, o.get('unknown', 2))

        with self.assertRaises(AttributeError):
            o['baz']
  def test_is_flagged(self):
    o = OptionValueContainer()

    o.foo = RankedValue(RankedValue.NONE, 11)
    self.assertFalse(o.is_flagged('foo'))

    o.foo = RankedValue(RankedValue.CONFIG, 11)
    self.assertFalse(o.is_flagged('foo'))

    o.foo = RankedValue(RankedValue.ENVIRONMENT, 11)
    self.assertFalse(o.is_flagged('foo'))

    o.foo = RankedValue(RankedValue.FLAG, 11)
    self.assertTrue(o.is_flagged('foo'))
 def test_value_ranking(self):
   o = OptionValueContainer()
   o.foo = RankedValue(RankedValue.CONFIG, 11)
   self.assertEqual(11, o.foo)
   self.assertEqual(RankedValue.CONFIG, o.get_rank('foo'))
   o.foo = RankedValue(RankedValue.HARDCODED, 22)
   self.assertEqual(11, o.foo)
   self.assertEqual(RankedValue.CONFIG, o.get_rank('foo'))
   o.foo = RankedValue(RankedValue.ENVIRONMENT, 33)
   self.assertEqual(33, o.foo)
   self.assertEqual(RankedValue.ENVIRONMENT, o.get_rank('foo'))
   o.foo = RankedValue(RankedValue.FLAG, 44)
   self.assertEqual(44, o.foo)
   self.assertEqual(RankedValue.FLAG, o.get_rank('foo'))
Example #30
0
def _create_scoped_options(
        default_rank: Rank, **options: Union[RankedValue,
                                             Value]) -> OptionValueContainer:
    scoped_options = OptionValueContainer()
    for key, value in options.items():
        if not isinstance(value, RankedValue):
            value = RankedValue(default_rank, value)
        setattr(scoped_options, key, value)
    return scoped_options
Example #31
0
 def test_value_ranking(self):
     o = OptionValueContainer()
     o.add_forwardings({'foo': 'bar'})
     o.bar = RankedValue(RankedValue.CONFIG, 11)
     self.assertEqual(11, o.foo)
     o.bar = RankedValue(RankedValue.HARDCODED, 22)
     self.assertEqual(11, o.foo)
     o.bar = RankedValue(RankedValue.ENVIRONMENT, 33)
     self.assertEqual(33, o.foo)
     o.bar = 44  # No explicit rank is assumed to be a FLAG.
     self.assertEqual(44, o.foo)
 def test_iterator(self):
   o = OptionValueContainer()
   o.add_forwardings({'a': '_a'})
   o.add_forwardings({'b': '_b'})
   o.add_forwardings({'b_prime': '_b'})  # Should be elided in favor of b.
   o.add_forwardings({'c': '_c'})
   names = list(iter(o))
   self.assertListEqual(['a', 'b', 'c'], names)
  def test_forwarding(self):
    o = OptionValueContainer()
    o.add_forwardings({'foo': 'bar'})
    o.bar = 1
    self.assertEqual(1, o.foo)
    o.bar = 2
    self.assertEqual(2, o.foo)

    o.add_forwardings({'baz': 'qux'})
    o.qux = 3
    self.assertEqual(2, o.foo)
    self.assertEqual(3, o.baz)

    # Direct setting overrides forwarding.
    o.foo = 4
    self.assertEqual(4, o.foo)
Example #34
0
    def test_resolve_conflicting_options(self) -> None:
        resolve_options = partial(
            resolve_conflicting_options,
            old_option="my_opt",
            new_option="my_opt",
            old_scope="old-scope",
            new_scope="new-scope",
        )
        old_val = "ancient"
        new_val = "modern"
        old_default_rv = RankedValue(RankedValue.HARDCODED, old_val)
        new_default_rv = RankedValue(RankedValue.HARDCODED, new_val)
        old_configured_rv = RankedValue(RankedValue.FLAG, old_val)
        new_configured_rv = RankedValue(RankedValue.FLAG, new_val)

        def assert_option_resolved(
            *,
            old_configured: bool = False,
            new_configured: bool = False,
            expected: str,
        ) -> None:
            old_container, new_container = OptionValueContainer(
            ), OptionValueContainer()
            old_container.my_opt = old_configured_rv if old_configured else old_default_rv
            new_container.my_opt = new_configured_rv if new_configured else new_default_rv
            assert resolve_options(old_container=old_container,
                                   new_container=new_container) == expected

        assert_option_resolved(expected=new_val)
        assert_option_resolved(old_configured=True, expected=old_val)
        assert_option_resolved(new_configured=True, expected=new_val)

        # both configured -> raise an error
        old_container, new_container = OptionValueContainer(
        ), OptionValueContainer()
        old_container.my_opt = old_configured_rv
        new_container.my_opt = new_configured_rv
        with pytest.raises(ValueError) as e:
            resolve_options(old_container=old_container,
                            new_container=new_container)
        assert "--old-scope-my-opt" in str(e.value)
        assert "--new-scope-my-opt" in str(e.value)
  def test_indexing(self):
    o = OptionValueContainer()
    o.add_forwardings({'foo': 'bar'})
    o.bar = 1
    self.assertEqual(1, o['foo'])
    self.assertEqual(1, o['bar'])

    self.assertEqual(1, o.get('foo'))
    self.assertEqual(1, o.get('foo', 2))
    self.assertIsNone(o.get('unknown'))
    self.assertEqual(2, o.get('unknown', 2))

    with self.assertRaises(AttributeError):
      o['baz']
 def test_deepcopy(self):
     # deepcopy semantics can get hairy when overriding __setattr__/__getattr__, so we test them.
     o = OptionValueContainer()
     o.add_forwardings({'foo': 'bar'})
     o.add_forwardings({'baz': 'qux'})
     o.bar = 1
     o.qux = {'a': 111}
     p = copy.deepcopy(o)
     o.baz['b'] = 222  # Add to original dict.
     self.assertEqual(1, p.foo)
     self.assertEqual({'a': 111}, p.baz)  # Ensure dict was copied.
 def test_value_ranking(self):
   o = OptionValueContainer()
   o.add_forwardings({'foo': 'bar'})
   o.bar = RankedValue(RankedValue.CONFIG, 11)
   self.assertEqual(11, o.foo)
   o.bar = RankedValue(RankedValue.HARDCODED, 22)
   self.assertEqual(11, o.foo)
   o.bar = RankedValue(RankedValue.ENVIRONMENT, 33)
   self.assertEqual(33, o.foo)
   o.bar = 44  # No explicit rank is assumed to be a FLAG.
   self.assertEqual(44, o.foo)
Example #38
0
    def test_indexing(self):
        o = OptionValueContainer()
        o.foo = RankedValue(RankedValue.CONFIG, 1)
        self.assertEqual(1, o['foo'])

        self.assertEqual(1, o.get('foo'))
        self.assertEqual(1, o.get('foo', 2))
        self.assertIsNone(o.get('unknown'))
        self.assertEqual(2, o.get('unknown', 2))

        with self.assertRaises(AttributeError):
            o['bar']
Example #39
0
    def test_indexing(self) -> None:
        o = OptionValueContainer()
        o.foo = RankedValue(RankedValue.CONFIG, 1)
        self.assertEqual(1, o["foo"])

        self.assertEqual(1, o.get("foo"))
        self.assertEqual(1, o.get("foo", 2))
        self.assertIsNone(o.get("unknown"))
        self.assertEqual(2, o.get("unknown", 2))

        with self.assertRaises(AttributeError):
            o["bar"]
 def test_copy(self):
   # copy semantics can get hairy when overriding __setattr__/__getattr__, so we test them.
   o = OptionValueContainer()
   o.add_forwardings({'foo': 'bar'})
   o.add_forwardings({'baz': 'qux'})
   o.bar = 1
   o.qux = { 'a': 111 }
   p = copy.copy(o)
   o.baz['b'] = 222  # Add to original dict.
   self.assertEqual(1, p.foo)
   self.assertEqual({ 'a': 111, 'b': 222 }, p.baz)  # Ensure dict was not copied.
Example #41
0
 def _format_for_global_scope(show_advanced, show_deprecated, args, kwargs):
     parser = Parser(
         env={},
         config=Config.load([]),
         scope_info=GlobalOptions.get_scope_info(),
         parent_parser=None,
     )
     parser.register(*args, **kwargs)
     # Force a parse to generate the derivation history.
     parser.parse_args(
         Parser.ParseArgsRequest((), OptionValueContainer(), lambda: [], 0,
                                 []))
     oshi = HelpInfoExtracter("").get_option_scope_help_info(
         "", parser, False)
     return HelpFormatter(show_advanced=show_advanced,
                          show_deprecated=show_deprecated,
                          color=False).format_options(oshi)
  def test_indexing(self):
    o = OptionValueContainer()
    o.foo = RankedValue(RankedValue.CONFIG, 1)
    self.assertEqual(1, o['foo'])

    self.assertEqual(1, o.get('foo'))
    self.assertEqual(1, o.get('foo', 2))
    self.assertIsNone(o.get('unknown'))
    self.assertEqual(2, o.get('unknown', 2))

    with self.assertRaises(AttributeError):
      o['bar']
Example #43
0
  def for_scope(self, scope):
    """Return the option values for the given scope.

    Values are attributes of the returned object, e.g., options.foo.
    Computed lazily per scope.
    """
    # Short-circuit, if already computed.
    if scope in self._values_by_scope:
      return self._values_by_scope[scope]

    # First get enclosing scope's option values, if any.
    if scope == GLOBAL_SCOPE:
      values = OptionValueContainer()
    else:
      values = copy.deepcopy(self.for_scope(scope.rpartition('.')[0]))

    # Now add our values.
    flags_in_scope = self._scope_to_flags.get(scope, [])
    self._parser_hierarchy.get_parser_by_scope(scope).parse_args(flags_in_scope, values)
    self._values_by_scope[scope] = values
    return values
    def test_deepcopy(self):
        # copy semantics can get hairy when overriding __setattr__/__getattr__, so we test them.
        o = OptionValueContainer()
        o.foo = 1
        o.bar = {'a': 111}

        p = copy.deepcopy(o)

        # Verify that the result is in fact a copy.
        self.assertEqual(1, p.foo)  # Has original attribute.
        o.baz = 42
        self.assertFalse(hasattr(
            p, 'baz'))  # Does not have attribute added after the copy.

        # Verify that it's a deep copy by modifying a referent in o and reading it in p.
        o.bar['b'] = 222
        self.assertEqual({'a': 111}, p.bar)
Example #45
0
    def test_deepcopy(self) -> None:
        # copy semantics can get hairy when overriding __setattr__/__getattr__, so we test them.
        o = OptionValueContainer()
        o.foo = RankedValue(RankedValue.FLAG, 1)
        o.bar = RankedValue(RankedValue.FLAG, {"a": 111})

        p = copy.deepcopy(o)

        # Verify that the result is in fact a copy.
        self.assertEqual(1, p.foo)  # Has original attribute.
        o.baz = RankedValue(RankedValue.FLAG, 42)
        self.assertFalse(hasattr(p, "baz"))  # Does not have attribute added after the copy.

        # Verify that it's a deep copy by modifying a referent in o and reading it in p.
        # TODO: add type hints to ranked_value.py and option_value_container.py so that this works.
        o.bar["b"] = 222  # type: ignore[index]
        self.assertEqual({"a": 111}, p.bar)
Example #46
0
def test_scope_existence() -> None:
    class NoScope(Subsystem):
        pass

    with pytest.raises(OptionsError) as excinfo:
        NoScope.get_scope_info()
    assert "NoScope must set options_scope" in str(excinfo.value)

    with pytest.raises(OptionsError) as excinfo:
        NoScope(OptionValueContainer({}))
    assert "NoScope must set options_scope" in str(excinfo.value)

    class StringScope(Subsystem):
        options_scope = "good"

    assert "good" == StringScope.options_scope

    class Intermediate(Subsystem):
        pass

    class Indirect(Intermediate):
        options_scope = "good"

    assert "good" == Indirect.options_scope
    def test_is_flagged(self):
        o = OptionValueContainer()
        o.add_forwardings({'foo': 'bar'})

        o.bar = RankedValue(RankedValue.NONE, 11)
        self.assertFalse(o.is_flagged('foo'))

        o.bar = RankedValue(RankedValue.CONFIG, 11)
        self.assertFalse(o.is_flagged('foo'))

        o.bar = RankedValue(RankedValue.ENVIRONMENT, 11)
        self.assertFalse(o.is_flagged('foo'))

        o.bar = RankedValue(RankedValue.FLAG, 11)
        self.assertTrue(o.is_flagged('foo'))
  def test_is_flagged(self):
    o = OptionValueContainer()
    o.add_forwardings({'foo': 'bar'})

    o.bar = RankedValue(RankedValue.NONE, 11)
    self.assertFalse(o.is_flagged('foo'))

    o.bar = RankedValue(RankedValue.CONFIG, 11)
    self.assertFalse(o.is_flagged('foo'))

    o.bar = RankedValue(RankedValue.ENVIRONMENT, 11)
    self.assertFalse(o.is_flagged('foo'))

    o.bar = RankedValue(RankedValue.FLAG, 11)
    self.assertTrue(o.is_flagged('foo'))