aboutsummaryrefslogtreecommitdiff
path: root/absl/flags/tests
AgeCommit message (Collapse)Author
2022-09-20Add a flags.set_default function.Abseil Team
PiperOrigin-RevId: 475611494 Change-Id: I9facdfcaece0b3c0bd2b0b38364ecd41cb06d79c
2022-09-13Support FlagHolders in flag module-level functions.Abseil Team
PiperOrigin-RevId: 474195462 Change-Id: I2b57d8ea6b8eb66d1f777f026fb19e5401983789
2022-09-09Remove Python 2 compat code.Abseil Team
PiperOrigin-RevId: 473306343 Change-Id: I4c166f7fa34ce2f1b0bcacafbf790d4f932886d1
2022-06-08Remove the unnecessary Python 2 related future imports.Yilei Yang
PiperOrigin-RevId: 453697925 Change-Id: I24a9fbbe2a690d7101b7190f4b4976d16bd0942f
2022-03-22Remove the use of third party `mock` package and future imports in these tests.Yilei Yang
Also remove the mock package in bazel WORKSPACE file. PiperOrigin-RevId: 436585035 Change-Id: I7f8eafac5f7b10dc8f580db20c7ae60711dfdf12
2022-02-22Enumerate possible values in multi_enum flag help.Abseil Team
PiperOrigin-RevId: 430280700 Change-Id: I62ca45c7b794989f9e8ee66094fb73c5ac7a6840
2022-02-08Prevent the truthiness of absl.flags Flag instances from being tested in a ↵Gregory P. Smith
bool context (not useful) to avoid situations where someone really wanted to refer to `their_flag.value` instead. This prevents logic bugs. There were ~10 problems found by this and cleaned up in our internal codebase. PiperOrigin-RevId: 427295923 Change-Id: Ifc9e086133986cc14d052a06889a93c1ab0ff688
2022-01-24Remove PY2-ism in absl's own unit tests.Yilei Yang
PiperOrigin-RevId: 423878454 Change-Id: Iadc82651ecd39954cfd2af6b4bae2a98388fd75b
2022-01-20Merge changes from github.Yilei Yang
PiperOrigin-RevId: 423095241 Change-Id: Ie78fb886746b11320e777587bf50c938d9054e37
2021-10-25Drop the support of Python 2.7, 3.4, and 3.5. All versions have reached ↵Yilei Yang
end-of-life for more than a year now. PiperOrigin-RevId: 405511743 Change-Id: Id0f78693a6de9474576c3cfa879caf2cc177d8f6
2021-07-26absl: Expose the `.present` property from `Flag` on `FlagHolder`Abseil Team
The `FlagHolder` object is returned from `flags.DEFINE_*()` to allow type-safe and fully-declared access via `myflag.value`, instead of requiring users to write `FLAGS.myflag`. Additionally, this proxies the `.default` property from the `Flag` object underlying the `FlagHolder`, so `FLAGS['myflag'].default` can instead be written as simply `myflag.default`. However, the `.present` property is not easily available today without writing `FLAGS['myflag'].present` or `FLAGS[myflag.name].present`, despite being relatively commonly used. Since it intuitively makes sense for this to be available, let's proxy it through `FlagHolder` to the underlying `Flag` object. PiperOrigin-RevId: 386901861 Change-Id: I29e3173668080957b796c8634527382b792aa4ec
2021-07-19Fix #171: add an ignored `default=` argument to our custom actions.Yilei Yang
This is a required argument for custom argparse.Action classes, and is used when the `ArgumentParse` is created with a `argument_default=`. PiperOrigin-RevId: 385601086 Change-Id: I01ef4870aa4f0e92f7e8f9be0125c9a0dba16c6f
2021-04-30Shows all missing required flags in error message, instead of just the first ↵Abseil Team
missing required flag. Given these required flags of float values with default value of None: flags.mark_flags_as_required(["x", "y", "z"]) If none of the required flags are passed as arguments, the resulting error will only show the first missing required flag as an issue: FATAL Flags parsing error: flag --x=None: Flag --x must have a value other than None. The user will then add this required flag "x" and try again, but then get the error for "y" as a missing requirement. This loops until the user finally passes all the required flags as arguments. Since we already know which flags are required, this changes the error message shows all missing required flags at once, so the user can make the necessary changes in a single pass with the error message showing this: FATAL Flags parsing error: flag --x=None: Flag --x must have a value other than None. flag --y=None: Flag --y must have a value other than None. flag --z=None: Flag --z must have a value other than None. To achieve the formatting change, `app.parse_flags_with_usage` now puts the error message on a new line and adds indentation if the message is multi-line string. PiperOrigin-RevId: 371414012 Change-Id: Id7456e9c293fb95d7b4551fd28441610af9b3030
2021-03-04Expose the --test_tmpdir and --test_srcdir flags as public flag holders.Yilei Yang
They are considered as public flags and callers should use them instead of accessing FLAGS.test_tmpdir and FLAGS.test_srcdir. PiperOrigin-RevId: 360948844 Change-Id: Ib3673ae55ad9b55000fb80ba60647a93fdfc0426
2021-02-26Add EnumClassListSerializer to the public namespaceAbseil Team
This is to (formally) allow using it in extension libraries. Also add a test to cover non-comma separators. PiperOrigin-RevId: 359820150 Change-Id: I3a384083a1634d1429b6a01b10571ebfb7ee9ac1
2021-02-12Fix CsvListSerializer to honor its list_sep parameter.Abseil Team
PiperOrigin-RevId: 357245847 Change-Id: I7637199f61f23e78646720ad406f539c89962fe3
2020-12-23Add a required argument to DEFINE_* methods.Abseil Team
Setting it to true, is functionally equivalent to calling `flags.mark_flag_as_required(flag_name)`, but changes the type of returned flagholder. ``` _A : FlagHolder[Optional[str]] = flags.DEFINE_string( name='a', default=None, help='help') flags.mark_flag_as_required('a') ``` v/s ``` _A : FlagHolder[str] = flags.DEFINE_string( name='a', default=None, help='help', required=True) ``` PiperOrigin-RevId: 348825600 Change-Id: Ia7610af1b5c4649c20aba5cbb620eae1359ad592
2020-10-22Surface inappropriate usage of a `FlagHolder` object as a runtime errorMatt McDonald
With the aim of steering users away from potential pitfalls in usage of the `FlagHolder` API, this change introduces implementation overrides for the class `__eq__` and `__bool__` methods which turn any such usage into a `TypeError` at runtime. This is to help avoid situations where a user neglects to use the `FlagHolder.value` property in cases where they intended to, e.g., ``` >>> SOME_FLAG = flags.DEFINE_boolean(...) >>> if SOME_FLAG: do_something() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: bool() not supported for instances of type 'FlagHolder' (did you mean to use 'FlagHolder.value' instead?) ``` PiperOrigin-RevId: 338473759 Change-Id: If3b6505a3bdca03db6d96ec7cc28e7214cb1a5e7
2020-09-30In flagsaver, set multiple flags together before their validators run.Karol M. Langner
This resolves an issue where multi-flag validators rely on specific flag combinations. PiperOrigin-RevId: 334625442 Change-Id: I7e6b625637a70356df57a4d9cbb01c203f14df4c
2020-08-03Make `DEFINE_enum_class` values case-insensitive by default.Abseil Team
This is to bridge the gap between lower case being idiomatic for command line values, and upper case for values defined in an `Enum`. It also makes it more consistent with `DEFINE_enum` usage, which usually uses lower case values. Case sensitivity can be restored by passing `case_sensitive=True`. When `case_sensitive=False` (the default), the associated flag serializers will lowercase enum member names. This seemed reasonable since help text that SCREAMS at you is inconsistent with the fact that member names will be provided most often in lowercase format. Internally, EnumParser is re-used for simplicity. PiperOrigin-RevId: 324594299 Change-Id: I2e15448ad00a095212756c5277b08219a9e84d55
2020-04-28Create --pdb as an alias of --pdb_post_mortemRichard Levasseur
This is to (1) make for an easier mnemonic and (2) to match the interfaces some other test frameworks (nose, pytest) provide. PiperOrigin-RevId: 308857342 Change-Id: Ideba06dc501a80ef41da9520f49bc18e0905f2a3
2020-04-27Add get_flags_for_module accessor.Richard Levasseur
This is an analogous access as get_key_flags_for_module, but for non-key flags. PiperOrigin-RevId: 308653262 Change-Id: I976b7ccb793b4de7b97993bf5128b786c6bc0797
2020-04-22Fix aliases from marking the aliased flag as present when the alias is defined.Richard Levasseur
This fixes a bug where the mere act of defining an alias flag would increment the aliased flag's `Flag.present` counter, thus incorrectly indicating the aliased flag was always present on the command line. This was happening because of the combination of the alias flag's custom flag parser and the initialization logic of `Flag`. Essentially, the alias used a custom parser which called the aliased flag's `Flag.parse` method, and the initialization logic of `Flag` calls the parser to convert the default value. Thus, when an alias was defined, the aliased flag's `parse()` method was called, which increments the `present` counter. Fixed by making the alias `Flag` subclass avoid calling the parser during initialization on the default value; the aliased flag already parsed it. Also fixes several bugs with aliases: * Aliasing a multi flag no longer causes the default value to be appended to after parsing. * The alias default value now matches the aliased default value. * The alias present counter correctly increments after parsing. (The aliased present counter still incorrectly increments, but that is a pre-existing bug). PiperOrigin-RevId: 307842972 Change-Id: If36672d4b4b2b261de6c87e7ccf3e595241522b8
2020-04-20Adds more tests to verify existing alias behaviors.Richard Levasseur
While working on a bug fix for aliases, I found seemingly small changes were having unexpected effects. To help prevent regressions, add tests covering more pre-existing alias behavior. Since there are a number of bugs, many asserts have comments indicating the incorrect value they have to assert. This is done in lieu of using @expectedFailure because most tests have several asserts, and I want to avoid subsequent fixes introducing unintentional changes. PiperOrigin-RevId: 307420078 Change-Id: I8fe8457d3152423b21fd3a84fc19516698f3d81d
2020-04-08Add logger level control flag, take 2.Richard Levasseur
This adds --logger_levels, a flag that allows setting the log levels of loggers by name. This makes it easy to adjust log levels on a per-logger basis without having to write application code to do so. Changes from original: * Use empty dict as the default value to work around some dependencies relying on the default matching the parsed value. * Return a copy instead of `MappingProxyType` because values are expected to be compatible with `copy.deepcopy()` PiperOrigin-RevId: 305493905 Change-Id: Ib826653b58d621aebc89aa1ded69647c534cde13
2020-04-07Add support for multi-flags to flag_dict_to_args helper.Abseil Team
Multi-flags are identified by an optional second argument consisting of a set of multi-flag names. PiperOrigin-RevId: 305287708 Change-Id: I26f1f1f40771d7e3a2d651812e6b3bf6fe3c5c17
2020-04-06Revert adding of --logger_level flag due to internal test failuresAbseil Team
PiperOrigin-RevId: 305120736 Change-Id: I1397f305c4471828bcdd22f07360d42522ec1b7c
2020-04-06Add logger level control flag.Richard Levasseur
This adds --logger_levels, a flag that allows setting the log levels of loggers by name. This makes it easy to adjust log levels on a per-logger basis without having to write application code to do so. PiperOrigin-RevId: 305079512 Change-Id: I9e350404aad02e9db040c106c7323e3b812d9186
2020-02-24Define and use py2 and py3 version of the test helper binaries, instead of ↵Yilei Yang
always using the PY2 version. PiperOrigin-RevId: 296947636 Change-Id: I07fd5bc14c6ff1f9b4f5150ba0a7637ca2b884cd
2020-02-20Remove the FlagHolder.non_none_value method for now, we might use a ↵Yilei Yang
different approach. Also the type annotations in _flagvalues.py should have _T instead of T. PiperOrigin-RevId: 296243519 Change-Id: I01cc7b8ef733ac78b671252a9afe8e7038c25d1b
2020-02-12DEFINE_* methods now return a FlagHolder instance and encourages coding ↵Abseil Team
pattern like ``` PORT = flags.DEFINE_integer('my_project_server_default_port', ...) def method(): PORT.value ``` Results in the name of the flag appears only once in the source code. - No more typoes. - Provides a local name - Linters can catch unused flags. - Plays well with type checkers PiperOrigin-RevId: 294778727 Change-Id: Ib1d1a7426968c59517e1c9f2f23962ba811ef914
2020-01-30FlagValues: Add method to validate all flagsAbseil Team
There is no way to explicitly trigger flag value validation programmatically after flags are parsed. This change makes the previously private "_assert_all_validators" method public under the name "validate_all_flags". PiperOrigin-RevId: 292307344 Change-Id: Ifd2429d439e353b88843821aa0c95e5dc95bf2aa
2019-11-12Update absl.testing's --test_randomize_ordering_seed flag default value from ↵Abseil Team
None to empty string. This doesn't change the behavior when the flag is using its default value. PiperOrigin-RevId: 280027756 Change-Id: I69261156b67bf20d31f5133cbb2d06287b8deb58
2019-07-16Make non-None flag tests assert warnings after capturing is finished.Richard Levasseur
Performing asserts on the warnings while they are being captured can fail if the asserts (or their helper code) triggers a warning. Fixes #108 PiperOrigin-RevId: 258438168 Change-Id: Ica91eb527445c25e258471a9e5003aaf3a713ab0
2019-04-11Make absl tests pass under new Bazel Python version transition logic.Richard Levasseur
This makes the absl tests pass when --incompatible_allow_python_version_transitions=true is set. Many tests use subprocesses to verify behavior and were relying on how the subprocess's Python version would match the test's Python version. Since this stickiness is going away, to keep the test and subprocess using the same Python version, the binaries have to be defined twice, one for each Python version, and a select() used with the test to select the matchiing binary. NOTE: Under bazel and Python 3, --python_version=PY3 flag must be specified so that bazel knows how to properly resolve selects. PiperOrigin-RevId: 243099319
2019-03-27Internal changeAbseil Team
PiperOrigin-RevId: 240662701
2019-03-21Add explicit tests for octal flags.Abseil Team
PiperOrigin-RevId: 239564996
2019-02-06Add a mark_bool_flags_as_mutual_exclusive convenience functionKarol M. Langner
PiperOrigin-RevId: 232764112
2019-01-09Change "should be specified" errors to "value other than None"Abseil Team
Previously, the error message for mark_flags_as_mutual_exclusive said "specified", but "specified" sounds like "included in the command-line invocation. That's not necessarily equivalent, in particular because flags can have default values other than None. mark_flags_required used a similar wording in the error message, but generated a warning when used with a flag with a default value other than None. Instead, make both generate a warning and clarify the error message for both to "should have a value other than None", since neither validator checks that a flag value was specified in the command-line invocation. The error message should still be clear in cases where the warning is suppressed or overlooked. Also adds a test for the existing warning behavior of mark_flag_as_required. PiperOrigin-RevId: 228510310
2018-12-19Allow defining multi fields with any Iterable, not just lists.Siavash Khodadadeh
This was motivated to allow tuples as input, but was expanded to allow any iterable. Strings and non-iterables are still special cased and converted to a single-element list. A copy of the input iterable is made so that the flag has sole ownership over the set of values. NOTE: Custom MultiFlag behavior change: The items of the iterable, rather than the iterable itself, are now passed onto the underlying self.parser object. Custom flags using DEFINE_multi or MultiFlag should update their custom flag code as appropriate. NOTE: Heavily modified from original PR to adjust for various lint/style errors and from the auto-formatter. Resolves #78 Closes #80 PiperOrigin-RevId: 226230348
2018-12-06Add multi enum class flag to absl.flags.Petros Maniatis
This change enables the use of enum.Enum objects in multi_* style labels. Previously the multi_enum flag in absl.flags only accepted strings. The new multi_enum_class flag accepts (lists of) Enum class members. The text format of lists of enums when serializing into XML differs from the list format in other multi_* types of flags. This is because all other multi_* types rely on repr() to turn a list into a string (since all other multi_* types have primitive contents). With multi_enum_class, repr() prints out a list of the repr()'s of Enum objects, which are rather unsightly for public consumption (e.g., they contain the integer value of the enum flags). This change does some acrobatics to ensure XML representation of flag usage looks reasonable for lists, but those rendered lists look a little different from repr()'ed lists. This change fixes the way multi_* flags are serialized when saved for future re-ingestion via a command line. It makes each flag value appear on a separate line, by modifying the list separator of all MultiFlag and subclasses to be '\n'. PiperOrigin-RevId: 224405076
2018-11-26Make flags_into_string deterministic.Richard Levasseur
This is (1) to match the c++ behavior and (2) so that build based upon the flag values are also deterministic. PiperOrigin-RevId: 222884822
2018-11-22Allow Enum class flags to correctly round-trip through serialize and parseAbseil Team
Previously the serialize method would prepend ClassName. to the value, which the parser would not accept. PiperOrigin-RevId: 222518525
2018-11-20Raise an error when pickling or copying FlagValues() (fixed version)Abseil Team
Deep copying flags (with copy.deepcopy) is still allowed. Pickling and shallow are now prohibited, because the notion of a shallow copy isn't entirely well defined -- should an unpickled flag or shallow copy link back to the original flag value? FlagValues() already cannot be successfully serialized/deserialized with pickle. But the error message is unrelated and raised when attempting to *load* pickled FlagValues instances, not when saving them: >>> from absl import flags >>> import pickle >>> dumped = pickle.dumps(flags.FLAGS) # no error >>> pickle.loads(dumped) Traceback (most recent call last) <ipython-input-5-5a8322d34219> in <module>() ----> 1 pickle.loads(dumped) /usr/lib/python2.7/pickle.pyc in loads(str) 1386 def loads(str): 1387 file = StringIO(str) -> 1388 return Unpickler(file).load() 1389 1390 # Doctest /usr/lib/python2.7/pickle.pyc in load(self) 862 while 1: 863 key = read(1) --> 864 dispatch[key](self) 865 except _Stop, stopinst: 866 return stopinst.value /usr/lib/python2.7/pickle.pyc in load_build(self) 1219 state = stack.pop() 1220 inst = stack[-1] -> 1221 setstate = getattr(inst, "__setstate__", None) 1222 if setstate: 1223 setstate(state) /usr/local/lib/python2.7/dist-packages/absl/flags/_flagvalues.pyc in __getattr__(self, name) 466 def __getattr__(self, name): 467 """Retrieves the 'value' attribute of the flag --name.""" --> 468 fl = self._flags() 469 if name not in fl: 470 raise AttributeError(name) /usr/local/lib/python2.7/dist-packages/absl/flags/_flagvalues.pyc in _flags(self) 139 140 def _flags(self): --> 141 return self.__dict__['__flags'] 142 143 def flags_by_module_dict(self): KeyError: '__flags' This change causes an error to be raised earlier (as part of serialization rather than deserialization) and with a better error message, e.g., >>> pickle.dumps(flags.FLAGS) TypeError: can't pickle FlagValues PiperOrigin-RevId: 222298474
2018-10-23Use Py3 assertRegex names in absl tests.Richard Levasseur
This is so the code is more naturally Py3 compatible. * Also converts assertRaisesRegex usages to use with statements PiperOrigin-RevId: 218399153
2018-09-20Automated g4 rollback of changelist 213728792Abseil Team
PiperOrigin-RevId: 213825654
2018-09-19Raise an error when pickling or copying FlagValues()Abseil Team
Deep copying flags (with copy.deepcopy) is still allowed. Pickling and shallow are now prohibited, because the notion of a shallow copy isn't entirely well defined -- should an unpickled flag or shallow copy link back to the original flag value? FlagValues() already cannot be successfully serialized/deserialized with pickle. But the error message is unrelated and raised when attempting to *load* pickled FlagValues instances, not when saving them: >>> from absl import flags >>> import pickle >>> dumped = pickle.dumps(flags.FLAGS) # no error >>> pickle.loads(dumped) Traceback (most recent call last) <ipython-input-5-5a8322d34219> in <module>() ----> 1 pickle.loads(dumped) /usr/lib/python2.7/pickle.pyc in loads(str) 1386 def loads(str): 1387 file = StringIO(str) -> 1388 return Unpickler(file).load() 1389 1390 # Doctest /usr/lib/python2.7/pickle.pyc in load(self) 862 while 1: 863 key = read(1) --> 864 dispatch[key](self) 865 except _Stop, stopinst: 866 return stopinst.value /usr/lib/python2.7/pickle.pyc in load_build(self) 1219 state = stack.pop() 1220 inst = stack[-1] -> 1221 setstate = getattr(inst, "__setstate__", None) 1222 if setstate: 1223 setstate(state) /usr/local/lib/python2.7/dist-packages/absl/flags/_flagvalues.pyc in __getattr__(self, name) 466 def __getattr__(self, name): 467 """Retrieves the 'value' attribute of the flag --name.""" --> 468 fl = self._flags() 469 if name not in fl: 470 raise AttributeError(name) /usr/local/lib/python2.7/dist-packages/absl/flags/_flagvalues.pyc in _flags(self) 139 140 def _flags(self): --> 141 return self.__dict__['__flags'] 142 143 def flags_by_module_dict(self): KeyError: '__flags' This change causes an error to be raised earlier (as part of serialization rather than deserialization) and with a better error message, e.g., >>> pickle.dumps(flags.FLAGS) TypeError: can't pickle FlagValues PiperOrigin-RevId: 213728792
2018-09-10Allow enum.Enum classes to be used directly with flags.Richard Levasseur
This adds a new flags define, `enum_class`, which is like `enum`, but uses an `enum.Enum` class as the source of valid values. The resulting parsed value is the corresponding Enum value. Using enum_class is recommended over plain enum. Python 2.7 note: The `enum` module is not required for absl in general, but is required to use `enum_class`, or for absl tests to fully pass. If the `enum` module isn't available, then absl flags can still be used, just not the `enum_class` function. The enum34 package on PyPI is the suggested package to use for enum support, and is the one absl assumes is used under Python 2.7. Python 2.7 and Bazel note: Because of how Bazel modifies PYTHONPATH, absl has to do do some special sys.path import manipulation to make the enum module work. In short, third party deps go before the stdlib on sys.path, so enum34's enum module shadows Python 3's enum module, which causes problems because enum34 is a subset of later Python 3's enum. So some sys.path futzing is done to account for this under Bazel. This only happens if 'import enum' initially fails, and only under Python 2.7. PiperOrigin-RevId: 212301566
2018-08-15Add validation to flag names checking no space is in the name. Also adds ↵Abseil Team
tests for current flag name validations like empty or non-string types. PiperOrigin-RevId: 208800538
2018-08-13Make absl flags integrate with argparse.Richard Levasseur
Argparse support is provided by two pieces: an argparse-compatible parser that understands absl flags, and app.run accepting a custom flag parser. argparse_flags.ArgumentParser is a custom argparse.ArgumentParser that makes absl defined flags available via the argparse APIs. The argparse_flags module contains more documentation. app.run accepts a flags_parser argument, which is responsible for parsing command line args and returning the value to pass onto main. The app.run function contains more documentation. Resolves issue #27 PiperOrigin-RevId: 208509632