aboutsummaryrefslogtreecommitdiff
path: root/absl/flags/_flagvalues.py
diff options
context:
space:
mode:
authorSadaf Ebrahimi <sadafebrahimi@google.com>2022-11-02 20:11:26 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2022-11-02 20:11:26 +0000
commitbd7cdd4d3776c9d08bbfea96d711958b24a9fe9c (patch)
treea5bf38c30b79f4a5ed56f02759efda543e1b3fac /absl/flags/_flagvalues.py
parentbe1c568746375d7558de3c65ad55ef1cb779694f (diff)
parent2f199605a9875340569e039657f8b4c72d51b84d (diff)
downloadabsl-py-bd7cdd4d3776c9d08bbfea96d711958b24a9fe9c.tar.gz
Upgrade abseil-py to v1.3.0 am: 4bcded2999 am: 393d0b1e3f am: 2f199605a9studio-2024.1.2-canary1studio-2024.1.1-canary8studio-2024.1.1-canary6studio-2024.1.1-beta2studio-2023.3.1-rc2studio-2023.3.1-canary8studio-2023.3.1-canary03studio-2023.3.1studio-2023.2.1-rc1studio-2023.2.1-beta02studio-2023.2.1android-14.0.0_r45android-14.0.0_r44android-14.0.0_r43android-14.0.0_r42android-14.0.0_r41android-14.0.0_r40android-14.0.0_r39android-14.0.0_r38android-14.0.0_r27android-14.0.0_r26android-14.0.0_r25android-14.0.0_r24android-14.0.0_r23android-14.0.0_r22android-14.0.0_r21android-14.0.0_r20android-14.0.0_r19android-14.0.0_r18android-14.0.0_r17android-14.0.0_r16aml_wif_341711020aml_wif_341610000aml_wif_341510000aml_wif_341410080aml_wif_341310010aml_wif_341110010aml_wif_341011010aml_wif_340913010aml_uwb_341710010aml_uwb_341513070aml_uwb_341511050aml_uwb_341310300aml_uwb_341310030aml_uwb_341111010aml_uwb_341011000aml_tz5_341510070aml_tz5_341510050aml_tz5_341510010aml_tet_341712060aml_tet_341610020aml_tet_341511010aml_tet_341411060aml_tet_341310230aml_tet_341112070aml_tet_341010040aml_tet_340913030aml_swc_341711000aml_swc_341619000aml_swc_341513600aml_swc_341312300aml_swc_341312020aml_swc_341111000aml_swc_341011020aml_swc_340922010aml_sta_341710000aml_sta_341615000aml_sta_341511040aml_sta_341410000aml_sta_341311010aml_sta_341114000aml_sta_341111000aml_sta_341010020aml_sta_340912000aml_sta_340911000aml_sdk_341710000aml_sdk_341510000aml_sdk_341410000aml_sdk_341110080aml_sdk_341110000aml_sdk_341010000aml_sdk_340912010aml_sch_341510000aml_rkp_341510000aml_rkp_341311000aml_rkp_341114000aml_rkp_341015010aml_rkp_341012000aml_res_341510000aml_res_341410010aml_res_341311030aml_res_341110000aml_res_340912000aml_per_341711000aml_per_341614000aml_per_341510010aml_per_341410020aml_per_341311000aml_per_341110020aml_per_341110010aml_per_341011100aml_per_341011020aml_per_340916010aml_odp_341717000aml_odp_341610000aml_neu_341510000aml_neu_341010080aml_neu_341010000aml_net_341710020aml_net_341610030aml_net_341510050aml_net_341510000aml_net_341411030aml_net_341311010aml_net_341310020aml_net_341111030aml_net_341014000aml_net_340913000aml_mpr_341713020aml_mpr_341614010aml_mpr_341511070aml_mpr_341411070aml_mpr_341313030aml_mpr_341111030aml_mpr_341111020aml_mpr_341015090aml_mpr_341015030aml_mpr_340919000aml_med_341711000aml_med_341619000aml_med_341513600aml_med_341312300aml_med_341312020aml_med_341111000aml_med_341011000aml_med_340922010aml_ips_341611000aml_ips_341510000aml_ips_340914280aml_ips_340914200aml_ips_340914000aml_hef_341717050aml_hef_341613000aml_hef_341512030aml_hef_341415040aml_hef_341311010aml_hef_341114030aml_ext_341716000aml_ext_341620040aml_ext_341518010aml_ext_341414010aml_ext_341317010aml_ext_341131030aml_ext_341027030aml_doc_341713000aml_doc_341610010aml_doc_341510050aml_doc_341312010aml_doc_341112000aml_doc_341012000aml_doc_340916000aml_con_341614000aml_con_341511080aml_con_341410300aml_con_341310090aml_con_341110000aml_cfg_341510000aml_cbr_341710000aml_cbr_341610000aml_cbr_341510010aml_cbr_341410010aml_cbr_341311010aml_cbr_341110000aml_cbr_341011000aml_cbr_340914000aml_ase_341510000aml_ase_341410000aml_ase_341310010aml_ase_341113000aml_ase_340913000aml_art_341711000aml_art_341615020aml_art_341514450aml_art_341514410aml_art_341411300aml_art_341311100aml_art_341110110aml_art_341110060aml_art_341010050aml_art_340915060aml_ads_341720000aml_ads_341615050aml_ads_341517040aml_ads_341413000aml_ads_341316030aml_ads_341131050aml_ads_341027030aml_ads_340915050aml_adb_341520010aml_adb_341517070aml_adb_340912530aml_adb_340912350aml_adb_340912200aml_adb_340912000android14-qpr1-s2-releaseandroid14-qpr1-releaseandroid14-mainline-wifi-releaseandroid14-mainline-uwb-releaseandroid14-mainline-tethering-releaseandroid14-mainline-sdkext-releaseandroid14-mainline-resolv-releaseandroid14-mainline-permission-releaseandroid14-mainline-os-statsd-releaseandroid14-mainline-networking-releaseandroid14-mainline-mediaprovider-releaseandroid14-mainline-media-swcodec-releaseandroid14-mainline-media-releaseandroid14-mainline-healthfitness-releaseandroid14-mainline-extservices-releaseandroid14-mainline-conscrypt-releaseandroid14-mainline-cellbroadcast-releaseandroid14-mainline-art-releaseandroid14-mainline-appsearch-releaseandroid14-mainline-adservices-releaseandroid14-mainline-adbd-releaseandroid14-devandroid14-d2-s5-releaseandroid14-d2-s4-releaseandroid14-d2-s3-releaseandroid14-d2-s2-releaseandroid14-d2-s1-releaseandroid14-d2-releaseaml_tz5_341510010
Original change: https://android-review.googlesource.com/c/platform/external/python/absl-py/+/2282959 Change-Id: Ia2df7395cbfbbd1b51cba3ef3325a3b60c382a6c Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
Diffstat (limited to 'absl/flags/_flagvalues.py')
-rw-r--r--absl/flags/_flagvalues.py139
1 files changed, 85 insertions, 54 deletions
diff --git a/absl/flags/_flagvalues.py b/absl/flags/_flagvalues.py
index 1b54fb3..937dc6c 100644
--- a/absl/flags/_flagvalues.py
+++ b/absl/flags/_flagvalues.py
@@ -37,36 +37,41 @@ _T = TypeVar('_T')
class FlagValues:
- """Registry of 'Flag' objects.
+ """Registry of :class:`~absl.flags.Flag` objects.
- A 'FlagValues' can then scan command line arguments, passing flag
+ A :class:`FlagValues` can then scan command line arguments, passing flag
arguments through to the 'Flag' objects that it owns. It also
provides easy access to the flag values. Typically only one
- 'FlagValues' object is needed by an application: flags.FLAGS
+ :class:`FlagValues` object is needed by an application:
+ :const:`FLAGS`.
This class is heavily overloaded:
- 'Flag' objects are registered via __setitem__:
+ :class:`Flag` objects are registered via ``__setitem__``::
+
FLAGS['longname'] = x # register a new flag
- The .value attribute of the registered 'Flag' objects can be accessed
- as attributes of this 'FlagValues' object, through __getattr__. Both
- the long and short name of the original 'Flag' objects can be used to
- access its value:
- FLAGS.longname # parsed flag value
- FLAGS.x # parsed flag value (short name)
+ The ``.value`` attribute of the registered :class:`~absl.flags.Flag` objects
+ can be accessed as attributes of this :class:`FlagValues` object, through
+ ``__getattr__``. Both the long and short name of the original
+ :class:`~absl.flags.Flag` objects can be used to access its value::
+
+ FLAGS.longname # parsed flag value
+ FLAGS.x # parsed flag value (short name)
+
+ Command line arguments are scanned and passed to the registered
+ :class:`~absl.flags.Flag` objects through the ``__call__`` method. Unparsed
+ arguments, including ``argv[0]`` (e.g. the program name) are returned::
- Command line arguments are scanned and passed to the registered 'Flag'
- objects through the __call__ method. Unparsed arguments, including
- argv[0] (e.g. the program name) are returned.
argv = FLAGS(sys.argv) # scan command line arguments
- The original registered Flag objects can be retrieved through the use
- of the dictionary-like operator, __getitem__:
+ The original registered :class:`~absl.flags.Flag` objects can be retrieved
+ through the use of the dictionary-like operator, ``__getitem__``::
+
x = FLAGS['longname'] # access the registered Flag object
- The str() operator of a 'FlagValues' object provides help for all of
- the registered 'Flag' objects.
+ The ``str()`` operator of a :class:`absl.flags.FlagValues` object provides
+ help for all of the registered :class:`~absl.flags.Flag` objects.
"""
# A note on collections.abc.Mapping:
@@ -407,11 +412,7 @@ class FlagValues:
fl = self._flags()
if not isinstance(flag, _flag.Flag):
raise _exceptions.IllegalFlagValueError(flag)
- if str is bytes and isinstance(name, unicode):
- # When using Python 2 with unicode_literals, allow it but encode it
- # into the bytes type we require.
- name = name.encode('utf-8')
- if not isinstance(name, type('')):
+ if not isinstance(name, str):
raise _exceptions.Error('Flag name must be a string')
if not name:
raise _exceptions.Error('Flag name cannot be empty')
@@ -627,7 +628,7 @@ class FlagValues:
TypeError: Raised on passing wrong type of arguments.
ValueError: Raised on flag value parsing error.
"""
- if _helpers.is_bytes_or_string(argv):
+ if isinstance(argv, (str, bytes)):
raise TypeError(
'argv should be a tuple/list of strings, not bytes or string.')
if not argv:
@@ -821,7 +822,7 @@ class FlagValues:
"""Explicitly marks flags as parsed.
Use this when the caller knows that this FlagValues has been parsed as if
- a __call__() invocation has happened. This is only a public method for
+ a ``__call__()`` invocation has happened. This is only a public method for
use by things like appcommands which do additional command like parsing.
"""
self.__dict__['__flags_parsed'] = True
@@ -1001,7 +1002,7 @@ class FlagValues:
def _is_flag_file_directive(self, flag_string):
"""Checks whether flag_string contain a --flagfile=<foo> directive."""
- if isinstance(flag_string, type('')):
+ if isinstance(flag_string, str):
if flag_string.startswith('--flagfile='):
return 1
elif flag_string == '--flagfile':
@@ -1133,14 +1134,15 @@ class FlagValues:
using absl.flags DEFINE_flag() type functions.
Notes (assuming we're getting a commandline of some sort as our input):
- --> For duplicate flags, the last one we hit should "win".
- --> Since flags that appear later win, a flagfile's settings can be "weak"
+
+ * For duplicate flags, the last one we hit should "win".
+ * Since flags that appear later win, a flagfile's settings can be "weak"
if the --flagfile comes at the beginning of the argument sequence,
and it can be "strong" if the --flagfile comes at the end.
- --> A further "--flagfile=<otherfile.cfg>" CAN be nested in a flagfile.
+ * A further "--flagfile=<otherfile.cfg>" CAN be nested in a flagfile.
It will be expanded in exactly the spot where it is found.
- --> In a flagfile, a line beginning with # or // is a comment.
- --> Entirely blank lines _should_ be ignored.
+ * In a flagfile, a line beginning with # or // is a comment.
+ * Entirely blank lines _should_ be ignored.
"""
rest_of_args = argv
new_argv = []
@@ -1296,29 +1298,25 @@ FLAGS = FlagValues()
class FlagHolder(Generic[_T]):
"""Holds a defined flag.
- This facilitates a cleaner api around global state. Instead of
-
- ```
- flags.DEFINE_integer('foo', ...)
- flags.DEFINE_integer('bar', ...)
- ...
- def method():
- # prints parsed value of 'bar' flag
- print(flags.FLAGS.foo)
- # runtime error due to typo or possibly bad coding style.
- print(flags.FLAGS.baz)
- ```
-
- it encourages code like
-
- ```
- FOO_FLAG = flags.DEFINE_integer('foo', ...)
- BAR_FLAG = flags.DEFINE_integer('bar', ...)
- ...
- def method():
- print(FOO_FLAG.value)
- print(BAR_FLAG.value)
- ```
+ This facilitates a cleaner api around global state. Instead of::
+
+ flags.DEFINE_integer('foo', ...)
+ flags.DEFINE_integer('bar', ...)
+
+ def method():
+ # prints parsed value of 'bar' flag
+ print(flags.FLAGS.foo)
+ # runtime error due to typo or possibly bad coding style.
+ print(flags.FLAGS.baz)
+
+ it encourages code like::
+
+ _FOO_FLAG = flags.DEFINE_integer('foo', ...)
+ _BAR_FLAG = flags.DEFINE_integer('bar', ...)
+
+ def method():
+ print(_FOO_FLAG.value)
+ print(_BAR_FLAG.value)
since the name of the flag appears only once in the source code.
"""
@@ -1364,7 +1362,8 @@ class FlagHolder(Generic[_T]):
def value(self):
"""Returns the value of the flag.
- If _ensure_non_none_value is True, then return value is not None.
+ If ``_ensure_non_none_value`` is ``True``, then return value is not
+ ``None``.
Raises:
UnparsedFlagAccessError: if flag parsing has not finished.
@@ -1385,3 +1384,35 @@ class FlagHolder(Generic[_T]):
def present(self):
"""Returns True if the flag was parsed from command-line flags."""
return bool(self._flagvalues[self._name].present)
+
+
+def resolve_flag_ref(flag_ref, flag_values):
+ """Helper to validate and resolve a flag reference argument."""
+ if isinstance(flag_ref, FlagHolder):
+ new_flag_values = flag_ref._flagvalues # pylint: disable=protected-access
+ if flag_values != FLAGS and flag_values != new_flag_values:
+ raise ValueError(
+ 'flag_values must not be customized when operating on a FlagHolder')
+ return flag_ref.name, new_flag_values
+ return flag_ref, flag_values
+
+
+def resolve_flag_refs(flag_refs, flag_values):
+ """Helper to validate and resolve flag reference list arguments."""
+ fv = None
+ names = []
+ for ref in flag_refs:
+ if isinstance(ref, FlagHolder):
+ newfv = ref._flagvalues # pylint: disable=protected-access
+ name = ref.name
+ else:
+ newfv = flag_values
+ name = ref
+ if fv and fv != newfv:
+ raise ValueError(
+ 'multiple FlagValues instances used in invocation. '
+ 'FlagHolders must be registered to the same FlagValues instance as '
+ 'do flag names, if provided.')
+ fv = newfv
+ names.append(name)
+ return names, fv