Kano001 commited on
Commit
375a1cf
1 Parent(s): bcbf5e5

Upload 919 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +2 -0
  2. MLPY/Lib/site-packages/__pycache__/isympy.cpython-39.pyc +0 -0
  3. MLPY/Lib/site-packages/__pycache__/pythoncom.cpython-39.pyc +0 -0
  4. MLPY/Lib/site-packages/__pycache__/six.cpython-39.pyc +0 -0
  5. MLPY/Lib/site-packages/__pycache__/typing_extensions.cpython-39.pyc +0 -0
  6. MLPY/Lib/site-packages/_distutils_hack/__init__.py +128 -0
  7. MLPY/Lib/site-packages/_distutils_hack/__pycache__/__init__.cpython-39.pyc +0 -0
  8. MLPY/Lib/site-packages/_distutils_hack/__pycache__/override.cpython-39.pyc +0 -0
  9. MLPY/Lib/site-packages/_distutils_hack/override.py +1 -0
  10. MLPY/Lib/site-packages/_yaml/__init__.py +33 -0
  11. MLPY/Lib/site-packages/_yaml/__pycache__/__init__.cpython-39.pyc +0 -0
  12. MLPY/Lib/site-packages/absl/__init__.py +13 -0
  13. MLPY/Lib/site-packages/absl/__pycache__/__init__.cpython-39.pyc +0 -0
  14. MLPY/Lib/site-packages/absl/__pycache__/app.cpython-39.pyc +0 -0
  15. MLPY/Lib/site-packages/absl/__pycache__/command_name.cpython-39.pyc +0 -0
  16. MLPY/Lib/site-packages/absl/app.py +480 -0
  17. MLPY/Lib/site-packages/absl/app.pyi +99 -0
  18. MLPY/Lib/site-packages/absl/command_name.py +63 -0
  19. MLPY/Lib/site-packages/absl/flags/__init__.py +225 -0
  20. MLPY/Lib/site-packages/absl/flags/__pycache__/__init__.cpython-39.pyc +0 -0
  21. MLPY/Lib/site-packages/absl/flags/__pycache__/_argument_parser.cpython-39.pyc +0 -0
  22. MLPY/Lib/site-packages/absl/flags/__pycache__/_defines.cpython-39.pyc +0 -0
  23. MLPY/Lib/site-packages/absl/flags/__pycache__/_exceptions.cpython-39.pyc +0 -0
  24. MLPY/Lib/site-packages/absl/flags/__pycache__/_flag.cpython-39.pyc +0 -0
  25. MLPY/Lib/site-packages/absl/flags/__pycache__/_flagvalues.cpython-39.pyc +0 -0
  26. MLPY/Lib/site-packages/absl/flags/__pycache__/_helpers.cpython-39.pyc +0 -0
  27. MLPY/Lib/site-packages/absl/flags/__pycache__/_validators.cpython-39.pyc +0 -0
  28. MLPY/Lib/site-packages/absl/flags/__pycache__/_validators_classes.cpython-39.pyc +0 -0
  29. MLPY/Lib/site-packages/absl/flags/__pycache__/argparse_flags.cpython-39.pyc +0 -0
  30. MLPY/Lib/site-packages/absl/flags/_argument_parser.py +638 -0
  31. MLPY/Lib/site-packages/absl/flags/_defines.py +1686 -0
  32. MLPY/Lib/site-packages/absl/flags/_exceptions.py +108 -0
  33. MLPY/Lib/site-packages/absl/flags/_flag.py +556 -0
  34. MLPY/Lib/site-packages/absl/flags/_flagvalues.py +1480 -0
  35. MLPY/Lib/site-packages/absl/flags/_helpers.py +421 -0
  36. MLPY/Lib/site-packages/absl/flags/_validators.py +352 -0
  37. MLPY/Lib/site-packages/absl/flags/_validators_classes.py +172 -0
  38. MLPY/Lib/site-packages/absl/flags/argparse_flags.py +388 -0
  39. MLPY/Lib/site-packages/absl/logging/__init__.py +1281 -0
  40. MLPY/Lib/site-packages/absl/logging/__init__.pyi +290 -0
  41. MLPY/Lib/site-packages/absl/logging/__pycache__/__init__.cpython-39.pyc +0 -0
  42. MLPY/Lib/site-packages/absl/logging/__pycache__/converter.cpython-39.pyc +0 -0
  43. MLPY/Lib/site-packages/absl/logging/converter.py +214 -0
  44. MLPY/Lib/site-packages/absl/testing/__init__.py +13 -0
  45. MLPY/Lib/site-packages/absl/testing/__pycache__/__init__.cpython-39.pyc +0 -0
  46. MLPY/Lib/site-packages/absl/testing/__pycache__/_bazelize_command.cpython-39.pyc +0 -0
  47. MLPY/Lib/site-packages/absl/testing/__pycache__/_pretty_print_reporter.cpython-39.pyc +0 -0
  48. MLPY/Lib/site-packages/absl/testing/__pycache__/absltest.cpython-39.pyc +0 -0
  49. MLPY/Lib/site-packages/absl/testing/__pycache__/flagsaver.cpython-39.pyc +0 -0
  50. MLPY/Lib/site-packages/absl/testing/__pycache__/parameterized.cpython-39.pyc +0 -0
.gitattributes CHANGED
@@ -75,3 +75,5 @@ MLPY/Library/bin/mkl_vml_mc3.1.dll filter=lfs diff=lfs merge=lfs -text
75
  MLPY/Library/bin/omptarget.rtl.level0.dll filter=lfs diff=lfs merge=lfs -text
76
  MLPY/Library/bin/omptarget.rtl.opencl.dll filter=lfs diff=lfs merge=lfs -text
77
  MLPY/Lib/site-packages/PyWin32.chm filter=lfs diff=lfs merge=lfs -text
 
 
 
75
  MLPY/Library/bin/omptarget.rtl.level0.dll filter=lfs diff=lfs merge=lfs -text
76
  MLPY/Library/bin/omptarget.rtl.opencl.dll filter=lfs diff=lfs merge=lfs -text
77
  MLPY/Lib/site-packages/PyWin32.chm filter=lfs diff=lfs merge=lfs -text
78
+ MLPY/Lib/site-packages/google/protobuf/pyext/_message.cp39-win_amd64.pyd filter=lfs diff=lfs merge=lfs -text
79
+ MLPY/Lib/site-packages/grpc/_cython/cygrpc.cp39-win_amd64.pyd filter=lfs diff=lfs merge=lfs -text
MLPY/Lib/site-packages/__pycache__/isympy.cpython-39.pyc ADDED
Binary file (9.4 kB). View file
 
MLPY/Lib/site-packages/__pycache__/pythoncom.cpython-39.pyc ADDED
Binary file (229 Bytes). View file
 
MLPY/Lib/site-packages/__pycache__/six.cpython-39.pyc ADDED
Binary file (27.5 kB). View file
 
MLPY/Lib/site-packages/__pycache__/typing_extensions.cpython-39.pyc ADDED
Binary file (102 kB). View file
 
MLPY/Lib/site-packages/_distutils_hack/__init__.py ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys
2
+ import os
3
+ import re
4
+ import importlib
5
+ import warnings
6
+
7
+
8
+ is_pypy = '__pypy__' in sys.builtin_module_names
9
+
10
+
11
+ warnings.filterwarnings('ignore',
12
+ r'.+ distutils\b.+ deprecated',
13
+ DeprecationWarning)
14
+
15
+
16
+ def warn_distutils_present():
17
+ if 'distutils' not in sys.modules:
18
+ return
19
+ if is_pypy and sys.version_info < (3, 7):
20
+ # PyPy for 3.6 unconditionally imports distutils, so bypass the warning
21
+ # https://foss.heptapod.net/pypy/pypy/-/blob/be829135bc0d758997b3566062999ee8b23872b4/lib-python/3/site.py#L250
22
+ return
23
+ warnings.warn(
24
+ "Distutils was imported before Setuptools, but importing Setuptools "
25
+ "also replaces the `distutils` module in `sys.modules`. This may lead "
26
+ "to undesirable behaviors or errors. To avoid these issues, avoid "
27
+ "using distutils directly, ensure that setuptools is installed in the "
28
+ "traditional way (e.g. not an editable install), and/or make sure "
29
+ "that setuptools is always imported before distutils.")
30
+
31
+
32
+ def clear_distutils():
33
+ if 'distutils' not in sys.modules:
34
+ return
35
+ warnings.warn("Setuptools is replacing distutils.")
36
+ mods = [name for name in sys.modules if re.match(r'distutils\b', name)]
37
+ for name in mods:
38
+ del sys.modules[name]
39
+
40
+
41
+ def enabled():
42
+ """
43
+ Allow selection of distutils by environment variable.
44
+ """
45
+ which = os.environ.get('SETUPTOOLS_USE_DISTUTILS', 'stdlib')
46
+ return which == 'local'
47
+
48
+
49
+ def ensure_local_distutils():
50
+ clear_distutils()
51
+ distutils = importlib.import_module('setuptools._distutils')
52
+ distutils.__name__ = 'distutils'
53
+ sys.modules['distutils'] = distutils
54
+
55
+ # sanity check that submodules load as expected
56
+ core = importlib.import_module('distutils.core')
57
+ assert '_distutils' in core.__file__, core.__file__
58
+
59
+
60
+ def do_override():
61
+ """
62
+ Ensure that the local copy of distutils is preferred over stdlib.
63
+
64
+ See https://github.com/pypa/setuptools/issues/417#issuecomment-392298401
65
+ for more motivation.
66
+ """
67
+ if enabled():
68
+ warn_distutils_present()
69
+ ensure_local_distutils()
70
+
71
+
72
+ class DistutilsMetaFinder:
73
+ def find_spec(self, fullname, path, target=None):
74
+ if path is not None:
75
+ return
76
+
77
+ method_name = 'spec_for_{fullname}'.format(**locals())
78
+ method = getattr(self, method_name, lambda: None)
79
+ return method()
80
+
81
+ def spec_for_distutils(self):
82
+ import importlib.abc
83
+ import importlib.util
84
+
85
+ class DistutilsLoader(importlib.abc.Loader):
86
+
87
+ def create_module(self, spec):
88
+ return importlib.import_module('setuptools._distutils')
89
+
90
+ def exec_module(self, module):
91
+ pass
92
+
93
+ return importlib.util.spec_from_loader('distutils', DistutilsLoader())
94
+
95
+ def spec_for_pip(self):
96
+ """
97
+ Ensure stdlib distutils when running under pip.
98
+ See pypa/pip#8761 for rationale.
99
+ """
100
+ if self.pip_imported_during_build():
101
+ return
102
+ clear_distutils()
103
+ self.spec_for_distutils = lambda: None
104
+
105
+ @staticmethod
106
+ def pip_imported_during_build():
107
+ """
108
+ Detect if pip is being imported in a build script. Ref #2355.
109
+ """
110
+ import traceback
111
+ return any(
112
+ frame.f_globals['__file__'].endswith('setup.py')
113
+ for frame, line in traceback.walk_stack(None)
114
+ )
115
+
116
+
117
+ DISTUTILS_FINDER = DistutilsMetaFinder()
118
+
119
+
120
+ def add_shim():
121
+ sys.meta_path.insert(0, DISTUTILS_FINDER)
122
+
123
+
124
+ def remove_shim():
125
+ try:
126
+ sys.meta_path.remove(DISTUTILS_FINDER)
127
+ except ValueError:
128
+ pass
MLPY/Lib/site-packages/_distutils_hack/__pycache__/__init__.cpython-39.pyc ADDED
Binary file (5.07 kB). View file
 
MLPY/Lib/site-packages/_distutils_hack/__pycache__/override.cpython-39.pyc ADDED
Binary file (203 Bytes). View file
 
MLPY/Lib/site-packages/_distutils_hack/override.py ADDED
@@ -0,0 +1 @@
 
 
1
+ __import__('_distutils_hack').do_override()
MLPY/Lib/site-packages/_yaml/__init__.py ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This is a stub package designed to roughly emulate the _yaml
2
+ # extension module, which previously existed as a standalone module
3
+ # and has been moved into the `yaml` package namespace.
4
+ # It does not perfectly mimic its old counterpart, but should get
5
+ # close enough for anyone who's relying on it even when they shouldn't.
6
+ import yaml
7
+
8
+ # in some circumstances, the yaml module we imoprted may be from a different version, so we need
9
+ # to tread carefully when poking at it here (it may not have the attributes we expect)
10
+ if not getattr(yaml, '__with_libyaml__', False):
11
+ from sys import version_info
12
+
13
+ exc = ModuleNotFoundError if version_info >= (3, 6) else ImportError
14
+ raise exc("No module named '_yaml'")
15
+ else:
16
+ from yaml._yaml import *
17
+ import warnings
18
+ warnings.warn(
19
+ 'The _yaml extension module is now located at yaml._yaml'
20
+ ' and its location is subject to change. To use the'
21
+ ' LibYAML-based parser and emitter, import from `yaml`:'
22
+ ' `from yaml import CLoader as Loader, CDumper as Dumper`.',
23
+ DeprecationWarning
24
+ )
25
+ del warnings
26
+ # Don't `del yaml` here because yaml is actually an existing
27
+ # namespace member of _yaml.
28
+
29
+ __name__ = '_yaml'
30
+ # If the module is top-level (i.e. not a part of any specific package)
31
+ # then the attribute should be set to ''.
32
+ # https://docs.python.org/3.8/library/types.html
33
+ __package__ = ''
MLPY/Lib/site-packages/_yaml/__pycache__/__init__.cpython-39.pyc ADDED
Binary file (706 Bytes). View file
 
MLPY/Lib/site-packages/absl/__init__.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2017 The Abseil Authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
MLPY/Lib/site-packages/absl/__pycache__/__init__.cpython-39.pyc ADDED
Binary file (141 Bytes). View file
 
MLPY/Lib/site-packages/absl/__pycache__/app.cpython-39.pyc ADDED
Binary file (13.9 kB). View file
 
MLPY/Lib/site-packages/absl/__pycache__/command_name.cpython-39.pyc ADDED
Binary file (1.63 kB). View file
 
MLPY/Lib/site-packages/absl/app.py ADDED
@@ -0,0 +1,480 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2017 The Abseil Authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Generic entry point for Abseil Python applications.
16
+
17
+ To use this module, define a ``main`` function with a single ``argv`` argument
18
+ and call ``app.run(main)``. For example::
19
+
20
+ def main(argv):
21
+ if len(argv) > 1:
22
+ raise app.UsageError('Too many command-line arguments.')
23
+
24
+ if __name__ == '__main__':
25
+ app.run(main)
26
+ """
27
+
28
+ import collections
29
+ import errno
30
+ import os
31
+ import pdb
32
+ import sys
33
+ import textwrap
34
+ import traceback
35
+
36
+ from absl import command_name
37
+ from absl import flags
38
+ from absl import logging
39
+
40
+ try:
41
+ import faulthandler
42
+ except ImportError:
43
+ faulthandler = None
44
+
45
+ FLAGS = flags.FLAGS
46
+
47
+ flags.DEFINE_boolean('run_with_pdb', False, 'Set to true for PDB debug mode')
48
+ flags.DEFINE_boolean('pdb_post_mortem', False,
49
+ 'Set to true to handle uncaught exceptions with PDB '
50
+ 'post mortem.')
51
+ flags.DEFINE_alias('pdb', 'pdb_post_mortem')
52
+ flags.DEFINE_boolean('run_with_profiling', False,
53
+ 'Set to true for profiling the script. '
54
+ 'Execution will be slower, and the output format might '
55
+ 'change over time.')
56
+ flags.DEFINE_string('profile_file', None,
57
+ 'Dump profile information to a file (for python -m '
58
+ 'pstats). Implies --run_with_profiling.')
59
+ flags.DEFINE_boolean('use_cprofile_for_profiling', True,
60
+ 'Use cProfile instead of the profile module for '
61
+ 'profiling. This has no effect unless '
62
+ '--run_with_profiling is set.')
63
+ flags.DEFINE_boolean('only_check_args', False,
64
+ 'Set to true to validate args and exit.',
65
+ allow_hide_cpp=True)
66
+
67
+
68
+ # If main() exits via an abnormal exception, call into these
69
+ # handlers before exiting.
70
+ EXCEPTION_HANDLERS = []
71
+
72
+
73
+ class Error(Exception):
74
+ pass
75
+
76
+
77
+ class UsageError(Error):
78
+ """Exception raised when the arguments supplied by the user are invalid.
79
+
80
+ Raise this when the arguments supplied are invalid from the point of
81
+ view of the application. For example when two mutually exclusive
82
+ flags have been supplied or when there are not enough non-flag
83
+ arguments. It is distinct from flags.Error which covers the lower
84
+ level of parsing and validating individual flags.
85
+ """
86
+
87
+ def __init__(self, message, exitcode=1):
88
+ super(UsageError, self).__init__(message)
89
+ self.exitcode = exitcode
90
+
91
+
92
+ class HelpFlag(flags.BooleanFlag):
93
+ """Special boolean flag that displays usage and raises SystemExit."""
94
+ NAME = 'help'
95
+ SHORT_NAME = '?'
96
+
97
+ def __init__(self):
98
+ super(HelpFlag, self).__init__(
99
+ self.NAME, False, 'show this help',
100
+ short_name=self.SHORT_NAME, allow_hide_cpp=True)
101
+
102
+ def parse(self, arg):
103
+ if self._parse(arg):
104
+ usage(shorthelp=True, writeto_stdout=True)
105
+ # Advertise --helpfull on stdout, since usage() was on stdout.
106
+ print()
107
+ print('Try --helpfull to get a list of all flags.')
108
+ sys.exit(1)
109
+
110
+
111
+ class HelpshortFlag(HelpFlag):
112
+ """--helpshort is an alias for --help."""
113
+ NAME = 'helpshort'
114
+ SHORT_NAME = None
115
+
116
+
117
+ class HelpfullFlag(flags.BooleanFlag):
118
+ """Display help for flags in the main module and all dependent modules."""
119
+
120
+ def __init__(self):
121
+ super(HelpfullFlag, self).__init__(
122
+ 'helpfull', False, 'show full help', allow_hide_cpp=True)
123
+
124
+ def parse(self, arg):
125
+ if self._parse(arg):
126
+ usage(writeto_stdout=True)
127
+ sys.exit(1)
128
+
129
+
130
+ class HelpXMLFlag(flags.BooleanFlag):
131
+ """Similar to HelpfullFlag, but generates output in XML format."""
132
+
133
+ def __init__(self):
134
+ super(HelpXMLFlag, self).__init__(
135
+ 'helpxml', False, 'like --helpfull, but generates XML output',
136
+ allow_hide_cpp=True)
137
+
138
+ def parse(self, arg):
139
+ if self._parse(arg):
140
+ flags.FLAGS.write_help_in_xml_format(sys.stdout)
141
+ sys.exit(1)
142
+
143
+
144
+ def parse_flags_with_usage(args):
145
+ """Tries to parse the flags, print usage, and exit if unparsable.
146
+
147
+ Args:
148
+ args: [str], a non-empty list of the command line arguments including
149
+ program name.
150
+
151
+ Returns:
152
+ [str], a non-empty list of remaining command line arguments after parsing
153
+ flags, including program name.
154
+ """
155
+ try:
156
+ return FLAGS(args)
157
+ except flags.Error as error:
158
+ message = str(error)
159
+ if '\n' in message:
160
+ final_message = 'FATAL Flags parsing error:\n%s\n' % textwrap.indent(
161
+ message, ' ')
162
+ else:
163
+ final_message = 'FATAL Flags parsing error: %s\n' % message
164
+ sys.stderr.write(final_message)
165
+ sys.stderr.write('Pass --helpshort or --helpfull to see help on flags.\n')
166
+ sys.exit(1)
167
+
168
+
169
+ _define_help_flags_called = False
170
+
171
+
172
+ def define_help_flags():
173
+ """Registers help flags. Idempotent."""
174
+ # Use a global to ensure idempotence.
175
+ global _define_help_flags_called
176
+
177
+ if not _define_help_flags_called:
178
+ flags.DEFINE_flag(HelpFlag())
179
+ flags.DEFINE_flag(HelpshortFlag()) # alias for --help
180
+ flags.DEFINE_flag(HelpfullFlag())
181
+ flags.DEFINE_flag(HelpXMLFlag())
182
+ _define_help_flags_called = True
183
+
184
+
185
+ def _register_and_parse_flags_with_usage(
186
+ argv=None,
187
+ flags_parser=parse_flags_with_usage,
188
+ ):
189
+ """Registers help flags, parses arguments and shows usage if appropriate.
190
+
191
+ This also calls sys.exit(0) if flag --only_check_args is True.
192
+
193
+ Args:
194
+ argv: [str], a non-empty list of the command line arguments including
195
+ program name, sys.argv is used if None.
196
+ flags_parser: Callable[[List[Text]], Any], the function used to parse flags.
197
+ The return value of this function is passed to `main` untouched.
198
+ It must guarantee FLAGS is parsed after this function is called.
199
+
200
+ Returns:
201
+ The return value of `flags_parser`. When using the default `flags_parser`,
202
+ it returns the following:
203
+ [str], a non-empty list of remaining command line arguments after parsing
204
+ flags, including program name.
205
+
206
+ Raises:
207
+ Error: Raised when flags_parser is called, but FLAGS is not parsed.
208
+ SystemError: Raised when it's called more than once.
209
+ """
210
+ if _register_and_parse_flags_with_usage.done:
211
+ raise SystemError('Flag registration can be done only once.')
212
+
213
+ define_help_flags()
214
+
215
+ original_argv = sys.argv if argv is None else argv
216
+ args_to_main = flags_parser(original_argv)
217
+ if not FLAGS.is_parsed():
218
+ raise Error('FLAGS must be parsed after flags_parser is called.')
219
+
220
+ # Exit when told so.
221
+ if FLAGS.only_check_args:
222
+ sys.exit(0)
223
+ # Immediately after flags are parsed, bump verbosity to INFO if the flag has
224
+ # not been set.
225
+ if FLAGS['verbosity'].using_default_value:
226
+ FLAGS.verbosity = 0
227
+ _register_and_parse_flags_with_usage.done = True
228
+
229
+ return args_to_main
230
+
231
+ _register_and_parse_flags_with_usage.done = False
232
+
233
+
234
+ def _run_main(main, argv):
235
+ """Calls main, optionally with pdb or profiler."""
236
+ if FLAGS.run_with_pdb:
237
+ sys.exit(pdb.runcall(main, argv))
238
+ elif FLAGS.run_with_profiling or FLAGS.profile_file:
239
+ # Avoid import overhead since most apps (including performance-sensitive
240
+ # ones) won't be run with profiling.
241
+ # pylint: disable=g-import-not-at-top
242
+ import atexit
243
+ if FLAGS.use_cprofile_for_profiling:
244
+ import cProfile as profile
245
+ else:
246
+ import profile
247
+ profiler = profile.Profile()
248
+ if FLAGS.profile_file:
249
+ atexit.register(profiler.dump_stats, FLAGS.profile_file)
250
+ else:
251
+ atexit.register(profiler.print_stats)
252
+ sys.exit(profiler.runcall(main, argv))
253
+ else:
254
+ sys.exit(main(argv))
255
+
256
+
257
+ def _call_exception_handlers(exception):
258
+ """Calls any installed exception handlers."""
259
+ for handler in EXCEPTION_HANDLERS:
260
+ try:
261
+ if handler.wants(exception):
262
+ handler.handle(exception)
263
+ except: # pylint: disable=bare-except
264
+ try:
265
+ # We don't want to stop for exceptions in the exception handlers but
266
+ # we shouldn't hide them either.
267
+ logging.error(traceback.format_exc())
268
+ except: # pylint: disable=bare-except
269
+ # In case even the logging statement fails, ignore.
270
+ pass
271
+
272
+
273
+ def run(
274
+ main,
275
+ argv=None,
276
+ flags_parser=parse_flags_with_usage,
277
+ ):
278
+ """Begins executing the program.
279
+
280
+ Args:
281
+ main: The main function to execute. It takes an single argument "argv",
282
+ which is a list of command line arguments with parsed flags removed.
283
+ The return value is passed to `sys.exit`, and so for example
284
+ a return value of 0 or None results in a successful termination, whereas
285
+ a return value of 1 results in abnormal termination.
286
+ For more details, see https://docs.python.org/3/library/sys#sys.exit
287
+ argv: A non-empty list of the command line arguments including program name,
288
+ sys.argv is used if None.
289
+ flags_parser: Callable[[List[Text]], Any], the function used to parse flags.
290
+ The return value of this function is passed to `main` untouched.
291
+ It must guarantee FLAGS is parsed after this function is called.
292
+ Should be passed as a keyword-only arg which will become mandatory in a
293
+ future release.
294
+ - Parses command line flags with the flag module.
295
+ - If there are any errors, prints usage().
296
+ - Calls main() with the remaining arguments.
297
+ - If main() raises a UsageError, prints usage and the error message.
298
+ """
299
+ try:
300
+ args = _run_init(
301
+ sys.argv if argv is None else argv,
302
+ flags_parser,
303
+ )
304
+ while _init_callbacks:
305
+ callback = _init_callbacks.popleft()
306
+ callback()
307
+ try:
308
+ _run_main(main, args)
309
+ except UsageError as error:
310
+ usage(shorthelp=True, detailed_error=error, exitcode=error.exitcode)
311
+ except:
312
+ exc = sys.exc_info()[1]
313
+ # Don't try to post-mortem debug successful SystemExits, since those
314
+ # mean there wasn't actually an error. In particular, the test framework
315
+ # raises SystemExit(False) even if all tests passed.
316
+ if isinstance(exc, SystemExit) and not exc.code:
317
+ raise
318
+
319
+ # Check the tty so that we don't hang waiting for input in an
320
+ # non-interactive scenario.
321
+ if FLAGS.pdb_post_mortem and sys.stdout.isatty():
322
+ traceback.print_exc()
323
+ print()
324
+ print(' *** Entering post-mortem debugging ***')
325
+ print()
326
+ pdb.post_mortem()
327
+ raise
328
+ except Exception as e:
329
+ _call_exception_handlers(e)
330
+ raise
331
+
332
+ # Callbacks which have been deferred until after _run_init has been called.
333
+ _init_callbacks = collections.deque()
334
+
335
+
336
+ def call_after_init(callback):
337
+ """Calls the given callback only once ABSL has finished initialization.
338
+
339
+ If ABSL has already finished initialization when ``call_after_init`` is
340
+ called then the callback is executed immediately, otherwise `callback` is
341
+ stored to be executed after ``app.run`` has finished initializing (aka. just
342
+ before the main function is called).
343
+
344
+ If called after ``app.run``, this is equivalent to calling ``callback()`` in
345
+ the caller thread. If called before ``app.run``, callbacks are run
346
+ sequentially (in an undefined order) in the same thread as ``app.run``.
347
+
348
+ Args:
349
+ callback: a callable to be called once ABSL has finished initialization.
350
+ This may be immediate if initialization has already finished. It
351
+ takes no arguments and returns nothing.
352
+ """
353
+ if _run_init.done:
354
+ callback()
355
+ else:
356
+ _init_callbacks.append(callback)
357
+
358
+
359
+ def _run_init(
360
+ argv,
361
+ flags_parser,
362
+ ):
363
+ """Does one-time initialization and re-parses flags on rerun."""
364
+ if _run_init.done:
365
+ return flags_parser(argv)
366
+ command_name.make_process_name_useful()
367
+ # Set up absl logging handler.
368
+ logging.use_absl_handler()
369
+ args = _register_and_parse_flags_with_usage(
370
+ argv=argv,
371
+ flags_parser=flags_parser,
372
+ )
373
+ if faulthandler:
374
+ try:
375
+ faulthandler.enable()
376
+ except Exception: # pylint: disable=broad-except
377
+ # Some tests verify stderr output very closely, so don't print anything.
378
+ # Disabled faulthandler is a low-impact error.
379
+ pass
380
+ _run_init.done = True
381
+ return args
382
+
383
+
384
+ _run_init.done = False
385
+
386
+
387
+ def usage(shorthelp=False, writeto_stdout=False, detailed_error=None,
388
+ exitcode=None):
389
+ """Writes __main__'s docstring to stderr with some help text.
390
+
391
+ Args:
392
+ shorthelp: bool, if True, prints only flags from the main module,
393
+ rather than all flags.
394
+ writeto_stdout: bool, if True, writes help message to stdout,
395
+ rather than to stderr.
396
+ detailed_error: str, additional detail about why usage info was presented.
397
+ exitcode: optional integer, if set, exits with this status code after
398
+ writing help.
399
+ """
400
+ if writeto_stdout:
401
+ stdfile = sys.stdout
402
+ else:
403
+ stdfile = sys.stderr
404
+
405
+ doc = sys.modules['__main__'].__doc__
406
+ if not doc:
407
+ doc = '\nUSAGE: %s [flags]\n' % sys.argv[0]
408
+ doc = flags.text_wrap(doc, indent=' ', firstline_indent='')
409
+ else:
410
+ # Replace all '%s' with sys.argv[0], and all '%%' with '%'.
411
+ num_specifiers = doc.count('%') - 2 * doc.count('%%')
412
+ try:
413
+ doc %= (sys.argv[0],) * num_specifiers
414
+ except (OverflowError, TypeError, ValueError):
415
+ # Just display the docstring as-is.
416
+ pass
417
+ if shorthelp:
418
+ flag_str = FLAGS.main_module_help()
419
+ else:
420
+ flag_str = FLAGS.get_help()
421
+ try:
422
+ stdfile.write(doc)
423
+ if flag_str:
424
+ stdfile.write('\nflags:\n')
425
+ stdfile.write(flag_str)
426
+ stdfile.write('\n')
427
+ if detailed_error is not None:
428
+ stdfile.write('\n%s\n' % detailed_error)
429
+ except IOError as e:
430
+ # We avoid printing a huge backtrace if we get EPIPE, because
431
+ # "foo.par --help | less" is a frequent use case.
432
+ if e.errno != errno.EPIPE:
433
+ raise
434
+ if exitcode is not None:
435
+ sys.exit(exitcode)
436
+
437
+
438
+ class ExceptionHandler(object):
439
+ """Base exception handler from which other may inherit."""
440
+
441
+ def wants(self, exc):
442
+ """Returns whether this handler wants to handle the exception or not.
443
+
444
+ This base class returns True for all exceptions by default. Override in
445
+ subclass if it wants to be more selective.
446
+
447
+ Args:
448
+ exc: Exception, the current exception.
449
+ """
450
+ del exc # Unused.
451
+ return True
452
+
453
+ def handle(self, exc):
454
+ """Do something with the current exception.
455
+
456
+ Args:
457
+ exc: Exception, the current exception
458
+
459
+ This method must be overridden.
460
+ """
461
+ raise NotImplementedError()
462
+
463
+
464
+ def install_exception_handler(handler):
465
+ """Installs an exception handler.
466
+
467
+ Args:
468
+ handler: ExceptionHandler, the exception handler to install.
469
+
470
+ Raises:
471
+ TypeError: Raised when the handler was not of the correct type.
472
+
473
+ All installed exception handlers will be called if main() exits via
474
+ an abnormal exception, i.e. not one of SystemExit, KeyboardInterrupt,
475
+ FlagsError or UsageError.
476
+ """
477
+ if not isinstance(handler, ExceptionHandler):
478
+ raise TypeError('handler of type %s does not inherit from ExceptionHandler'
479
+ % type(handler))
480
+ EXCEPTION_HANDLERS.append(handler)
MLPY/Lib/site-packages/absl/app.pyi ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ from typing import Any, Callable, Collection, Iterable, List, NoReturn, Optional, Text, TypeVar, Union, overload
3
+
4
+ from absl.flags import _flag
5
+
6
+
7
+ _MainArgs = TypeVar('_MainArgs')
8
+ _Exc = TypeVar('_Exc', bound=Exception)
9
+
10
+
11
+ class ExceptionHandler():
12
+
13
+ def wants(self, exc: _Exc) -> bool:
14
+ ...
15
+
16
+ def handle(self, exc: _Exc):
17
+ ...
18
+
19
+
20
+ EXCEPTION_HANDLERS: List[ExceptionHandler] = ...
21
+
22
+
23
+ class HelpFlag(_flag.BooleanFlag):
24
+ def __init__(self):
25
+ ...
26
+
27
+
28
+ class HelpshortFlag(HelpFlag):
29
+ ...
30
+
31
+
32
+ class HelpfullFlag(_flag.BooleanFlag):
33
+ def __init__(self):
34
+ ...
35
+
36
+
37
+ class HelpXMLFlag(_flag.BooleanFlag):
38
+ def __init__(self):
39
+ ...
40
+
41
+
42
+ def define_help_flags() -> None:
43
+ ...
44
+
45
+
46
+ @overload
47
+ def usage(shorthelp: Union[bool, int] = ...,
48
+ writeto_stdout: Union[bool, int] = ...,
49
+ detailed_error: Optional[Any] = ...,
50
+ exitcode: None = ...) -> None:
51
+ ...
52
+
53
+
54
+ @overload
55
+ def usage(shorthelp: Union[bool, int] = ...,
56
+ writeto_stdout: Union[bool, int] = ...,
57
+ detailed_error: Optional[Any] = ...,
58
+ exitcode: int = ...) -> NoReturn:
59
+ ...
60
+
61
+
62
+ def install_exception_handler(handler: ExceptionHandler) -> None:
63
+ ...
64
+
65
+
66
+ class Error(Exception):
67
+ ...
68
+
69
+
70
+ class UsageError(Error):
71
+ exitcode: int
72
+
73
+
74
+ def parse_flags_with_usage(args: List[Text]) -> List[Text]:
75
+ ...
76
+
77
+
78
+ def call_after_init(callback: Callable[[], Any]) -> None:
79
+ ...
80
+
81
+
82
+ # Without the flag_parser argument, `main` should require a List[Text].
83
+ @overload
84
+ def run(
85
+ main: Callable[[List[Text]], Any],
86
+ argv: Optional[List[Text]] = ...,
87
+ *,
88
+ ) -> NoReturn:
89
+ ...
90
+
91
+
92
+ @overload
93
+ def run(
94
+ main: Callable[[_MainArgs], Any],
95
+ argv: Optional[List[Text]] = ...,
96
+ *,
97
+ flags_parser: Callable[[List[Text]], _MainArgs],
98
+ ) -> NoReturn:
99
+ ...
MLPY/Lib/site-packages/absl/command_name.py ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2017 The Abseil Authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """A tiny stand alone library to change the kernel process name on Linux."""
16
+
17
+ import os
18
+ import sys
19
+
20
+ # This library must be kept small and stand alone. It is used by small things
21
+ # that require no extension modules.
22
+
23
+
24
+ def make_process_name_useful():
25
+ """Sets the process name to something better than 'python' if possible."""
26
+ set_kernel_process_name(os.path.basename(sys.argv[0]))
27
+
28
+
29
+ def set_kernel_process_name(name):
30
+ """Changes the Kernel's /proc/self/status process name on Linux.
31
+
32
+ The kernel name is NOT what will be shown by the ps or top command.
33
+ It is a 15 character string stored in the kernel's process table that
34
+ is included in the kernel log when a process is OOM killed.
35
+ The first 15 bytes of name are used. Non-ASCII unicode is replaced with '?'.
36
+
37
+ Does nothing if /proc/self/comm cannot be written or prctl() fails.
38
+
39
+ Args:
40
+ name: bytes|unicode, the Linux kernel's command name to set.
41
+ """
42
+ if not isinstance(name, bytes):
43
+ name = name.encode('ascii', 'replace')
44
+ try:
45
+ # This is preferred to using ctypes to try and call prctl() when possible.
46
+ with open('/proc/self/comm', 'wb') as proc_comm:
47
+ proc_comm.write(name[:15])
48
+ except EnvironmentError:
49
+ try:
50
+ import ctypes # pylint: disable=g-import-not-at-top
51
+ except ImportError:
52
+ return # No ctypes.
53
+ try:
54
+ libc = ctypes.CDLL('libc.so.6')
55
+ except EnvironmentError:
56
+ return # No libc.so.6.
57
+ pr_set_name = ctypes.c_ulong(15) # linux/prctl.h PR_SET_NAME value.
58
+ zero = ctypes.c_ulong(0)
59
+ try:
60
+ libc.prctl(pr_set_name, name, zero, zero, zero)
61
+ # Ignore the prctl return value. Nothing we can do if it errored.
62
+ except AttributeError:
63
+ return # No prctl.
MLPY/Lib/site-packages/absl/flags/__init__.py ADDED
@@ -0,0 +1,225 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2017 The Abseil Authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """This package is used to define and parse command line flags.
15
+
16
+ This package defines a *distributed* flag-definition policy: rather than
17
+ an application having to define all flags in or near main(), each Python
18
+ module defines flags that are useful to it. When one Python module
19
+ imports another, it gains access to the other's flags. (This is
20
+ implemented by having all modules share a common, global registry object
21
+ containing all the flag information.)
22
+
23
+ Flags are defined through the use of one of the DEFINE_xxx functions.
24
+ The specific function used determines how the flag is parsed, checked,
25
+ and optionally type-converted, when it's seen on the command line.
26
+ """
27
+
28
+ import getopt
29
+ import os
30
+ import re
31
+ import sys
32
+ import types
33
+ import warnings
34
+
35
+ from absl.flags import _argument_parser
36
+ from absl.flags import _defines
37
+ from absl.flags import _exceptions
38
+ from absl.flags import _flag
39
+ from absl.flags import _flagvalues
40
+ from absl.flags import _helpers
41
+ from absl.flags import _validators
42
+
43
+ __all__ = (
44
+ 'DEFINE',
45
+ 'DEFINE_flag',
46
+ 'DEFINE_string',
47
+ 'DEFINE_boolean',
48
+ 'DEFINE_bool',
49
+ 'DEFINE_float',
50
+ 'DEFINE_integer',
51
+ 'DEFINE_enum',
52
+ 'DEFINE_enum_class',
53
+ 'DEFINE_list',
54
+ 'DEFINE_spaceseplist',
55
+ 'DEFINE_multi',
56
+ 'DEFINE_multi_string',
57
+ 'DEFINE_multi_integer',
58
+ 'DEFINE_multi_float',
59
+ 'DEFINE_multi_enum',
60
+ 'DEFINE_multi_enum_class',
61
+ 'DEFINE_alias',
62
+ # Flag validators.
63
+ 'register_validator',
64
+ 'validator',
65
+ 'register_multi_flags_validator',
66
+ 'multi_flags_validator',
67
+ 'mark_flag_as_required',
68
+ 'mark_flags_as_required',
69
+ 'mark_flags_as_mutual_exclusive',
70
+ 'mark_bool_flags_as_mutual_exclusive',
71
+ # Flag modifiers.
72
+ 'set_default',
73
+ 'override_value',
74
+ # Key flag related functions.
75
+ 'declare_key_flag',
76
+ 'adopt_module_key_flags',
77
+ 'disclaim_key_flags',
78
+ # Module exceptions.
79
+ 'Error',
80
+ 'CantOpenFlagFileError',
81
+ 'DuplicateFlagError',
82
+ 'IllegalFlagValueError',
83
+ 'UnrecognizedFlagError',
84
+ 'UnparsedFlagAccessError',
85
+ 'ValidationError',
86
+ 'FlagNameConflictsWithMethodError',
87
+ # Public classes.
88
+ 'Flag',
89
+ 'BooleanFlag',
90
+ 'EnumFlag',
91
+ 'EnumClassFlag',
92
+ 'MultiFlag',
93
+ 'MultiEnumClassFlag',
94
+ 'FlagHolder',
95
+ 'FlagValues',
96
+ 'ArgumentParser',
97
+ 'BooleanParser',
98
+ 'EnumParser',
99
+ 'EnumClassParser',
100
+ 'ArgumentSerializer',
101
+ 'FloatParser',
102
+ 'IntegerParser',
103
+ 'BaseListParser',
104
+ 'ListParser',
105
+ 'ListSerializer',
106
+ 'EnumClassListSerializer',
107
+ 'CsvListSerializer',
108
+ 'WhitespaceSeparatedListParser',
109
+ 'EnumClassSerializer',
110
+ # Helper functions.
111
+ 'get_help_width',
112
+ 'text_wrap',
113
+ 'flag_dict_to_args',
114
+ 'doc_to_help',
115
+ # The global FlagValues instance.
116
+ 'FLAGS',
117
+ )
118
+
119
+ # Initialize the FLAGS_MODULE as early as possible.
120
+ # It's only used by adopt_module_key_flags to take SPECIAL_FLAGS into account.
121
+ _helpers.FLAGS_MODULE = sys.modules[__name__]
122
+
123
+ # Add current module to disclaimed module ids.
124
+ _helpers.disclaim_module_ids.add(id(sys.modules[__name__]))
125
+
126
+ # DEFINE functions. They are explained in more details in the module doc string.
127
+ # pylint: disable=invalid-name
128
+ DEFINE = _defines.DEFINE
129
+ DEFINE_flag = _defines.DEFINE_flag
130
+ DEFINE_string = _defines.DEFINE_string
131
+ DEFINE_boolean = _defines.DEFINE_boolean
132
+ DEFINE_bool = DEFINE_boolean # Match C++ API.
133
+ DEFINE_float = _defines.DEFINE_float
134
+ DEFINE_integer = _defines.DEFINE_integer
135
+ DEFINE_enum = _defines.DEFINE_enum
136
+ DEFINE_enum_class = _defines.DEFINE_enum_class
137
+ DEFINE_list = _defines.DEFINE_list
138
+ DEFINE_spaceseplist = _defines.DEFINE_spaceseplist
139
+ DEFINE_multi = _defines.DEFINE_multi
140
+ DEFINE_multi_string = _defines.DEFINE_multi_string
141
+ DEFINE_multi_integer = _defines.DEFINE_multi_integer
142
+ DEFINE_multi_float = _defines.DEFINE_multi_float
143
+ DEFINE_multi_enum = _defines.DEFINE_multi_enum
144
+ DEFINE_multi_enum_class = _defines.DEFINE_multi_enum_class
145
+ DEFINE_alias = _defines.DEFINE_alias
146
+ # pylint: enable=invalid-name
147
+
148
+ # Flag validators.
149
+ register_validator = _validators.register_validator
150
+ validator = _validators.validator
151
+ register_multi_flags_validator = _validators.register_multi_flags_validator
152
+ multi_flags_validator = _validators.multi_flags_validator
153
+ mark_flag_as_required = _validators.mark_flag_as_required
154
+ mark_flags_as_required = _validators.mark_flags_as_required
155
+ mark_flags_as_mutual_exclusive = _validators.mark_flags_as_mutual_exclusive
156
+ mark_bool_flags_as_mutual_exclusive = _validators.mark_bool_flags_as_mutual_exclusive
157
+
158
+ # Flag modifiers.
159
+ set_default = _defines.set_default
160
+ override_value = _defines.override_value
161
+
162
+ # Key flag related functions.
163
+ declare_key_flag = _defines.declare_key_flag
164
+ adopt_module_key_flags = _defines.adopt_module_key_flags
165
+ disclaim_key_flags = _defines.disclaim_key_flags
166
+
167
+ # Module exceptions.
168
+ # pylint: disable=invalid-name
169
+ Error = _exceptions.Error
170
+ CantOpenFlagFileError = _exceptions.CantOpenFlagFileError
171
+ DuplicateFlagError = _exceptions.DuplicateFlagError
172
+ IllegalFlagValueError = _exceptions.IllegalFlagValueError
173
+ UnrecognizedFlagError = _exceptions.UnrecognizedFlagError
174
+ UnparsedFlagAccessError = _exceptions.UnparsedFlagAccessError
175
+ ValidationError = _exceptions.ValidationError
176
+ FlagNameConflictsWithMethodError = _exceptions.FlagNameConflictsWithMethodError
177
+
178
+ # Public classes.
179
+ Flag = _flag.Flag
180
+ BooleanFlag = _flag.BooleanFlag
181
+ EnumFlag = _flag.EnumFlag
182
+ EnumClassFlag = _flag.EnumClassFlag
183
+ MultiFlag = _flag.MultiFlag
184
+ MultiEnumClassFlag = _flag.MultiEnumClassFlag
185
+ FlagHolder = _flagvalues.FlagHolder
186
+ FlagValues = _flagvalues.FlagValues
187
+ ArgumentParser = _argument_parser.ArgumentParser
188
+ BooleanParser = _argument_parser.BooleanParser
189
+ EnumParser = _argument_parser.EnumParser
190
+ EnumClassParser = _argument_parser.EnumClassParser
191
+ ArgumentSerializer = _argument_parser.ArgumentSerializer
192
+ FloatParser = _argument_parser.FloatParser
193
+ IntegerParser = _argument_parser.IntegerParser
194
+ BaseListParser = _argument_parser.BaseListParser
195
+ ListParser = _argument_parser.ListParser
196
+ ListSerializer = _argument_parser.ListSerializer
197
+ EnumClassListSerializer = _argument_parser.EnumClassListSerializer
198
+ CsvListSerializer = _argument_parser.CsvListSerializer
199
+ WhitespaceSeparatedListParser = _argument_parser.WhitespaceSeparatedListParser
200
+ EnumClassSerializer = _argument_parser.EnumClassSerializer
201
+ # pylint: enable=invalid-name
202
+
203
+ # Helper functions.
204
+ get_help_width = _helpers.get_help_width
205
+ text_wrap = _helpers.text_wrap
206
+ flag_dict_to_args = _helpers.flag_dict_to_args
207
+ doc_to_help = _helpers.doc_to_help
208
+
209
+ # Special flags.
210
+ _helpers.SPECIAL_FLAGS = FlagValues()
211
+
212
+ DEFINE_string(
213
+ 'flagfile', '',
214
+ 'Insert flag definitions from the given file into the command line.',
215
+ _helpers.SPECIAL_FLAGS) # pytype: disable=wrong-arg-types
216
+
217
+ DEFINE_string('undefok', '',
218
+ 'comma-separated list of flag names that it is okay to specify '
219
+ 'on the command line even if the program does not define a flag '
220
+ 'with that name. IMPORTANT: flags in this list that have '
221
+ 'arguments MUST use the --flag=value format.',
222
+ _helpers.SPECIAL_FLAGS) # pytype: disable=wrong-arg-types
223
+
224
+ #: The global FlagValues instance.
225
+ FLAGS = _flagvalues.FLAGS
MLPY/Lib/site-packages/absl/flags/__pycache__/__init__.cpython-39.pyc ADDED
Binary file (3.71 kB). View file
 
MLPY/Lib/site-packages/absl/flags/__pycache__/_argument_parser.cpython-39.pyc ADDED
Binary file (22.5 kB). View file
 
MLPY/Lib/site-packages/absl/flags/__pycache__/_defines.cpython-39.pyc ADDED
Binary file (38.2 kB). View file
 
MLPY/Lib/site-packages/absl/flags/__pycache__/_exceptions.cpython-39.pyc ADDED
Binary file (3.85 kB). View file
 
MLPY/Lib/site-packages/absl/flags/__pycache__/_flag.cpython-39.pyc ADDED
Binary file (18.4 kB). View file
 
MLPY/Lib/site-packages/absl/flags/__pycache__/_flagvalues.cpython-39.pyc ADDED
Binary file (44.1 kB). View file
 
MLPY/Lib/site-packages/absl/flags/__pycache__/_helpers.cpython-39.pyc ADDED
Binary file (9.92 kB). View file
 
MLPY/Lib/site-packages/absl/flags/__pycache__/_validators.cpython-39.pyc ADDED
Binary file (13.5 kB). View file
 
MLPY/Lib/site-packages/absl/flags/__pycache__/_validators_classes.cpython-39.pyc ADDED
Binary file (6.83 kB). View file
 
MLPY/Lib/site-packages/absl/flags/__pycache__/argparse_flags.cpython-39.pyc ADDED
Binary file (11.2 kB). View file
 
MLPY/Lib/site-packages/absl/flags/_argument_parser.py ADDED
@@ -0,0 +1,638 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2017 The Abseil Authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Contains base classes used to parse and convert arguments.
16
+
17
+ Do NOT import this module directly. Import the flags package and use the
18
+ aliases defined at the package level instead.
19
+ """
20
+
21
+ import collections
22
+ import csv
23
+ import enum
24
+ import io
25
+ import string
26
+ from typing import Generic, List, Iterable, Optional, Sequence, Text, Type, TypeVar, Union
27
+ from xml.dom import minidom
28
+
29
+ from absl.flags import _helpers
30
+
31
+ _T = TypeVar('_T')
32
+ _ET = TypeVar('_ET', bound=enum.Enum)
33
+ _N = TypeVar('_N', int, float)
34
+
35
+
36
+ def _is_integer_type(instance):
37
+ """Returns True if instance is an integer, and not a bool."""
38
+ return (isinstance(instance, int) and
39
+ not isinstance(instance, bool))
40
+
41
+
42
+ class _ArgumentParserCache(type):
43
+ """Metaclass used to cache and share argument parsers among flags."""
44
+
45
+ _instances = {}
46
+
47
+ def __call__(cls, *args, **kwargs):
48
+ """Returns an instance of the argument parser cls.
49
+
50
+ This method overrides behavior of the __new__ methods in
51
+ all subclasses of ArgumentParser (inclusive). If an instance
52
+ for cls with the same set of arguments exists, this instance is
53
+ returned, otherwise a new instance is created.
54
+
55
+ If any keyword arguments are defined, or the values in args
56
+ are not hashable, this method always returns a new instance of
57
+ cls.
58
+
59
+ Args:
60
+ *args: Positional initializer arguments.
61
+ **kwargs: Initializer keyword arguments.
62
+
63
+ Returns:
64
+ An instance of cls, shared or new.
65
+ """
66
+ if kwargs:
67
+ return type.__call__(cls, *args, **kwargs)
68
+ else:
69
+ instances = cls._instances
70
+ key = (cls,) + tuple(args)
71
+ try:
72
+ return instances[key]
73
+ except KeyError:
74
+ # No cache entry for key exists, create a new one.
75
+ return instances.setdefault(key, type.__call__(cls, *args))
76
+ except TypeError:
77
+ # An object in args cannot be hashed, always return
78
+ # a new instance.
79
+ return type.__call__(cls, *args)
80
+
81
+
82
+ class ArgumentParser(Generic[_T], metaclass=_ArgumentParserCache):
83
+ """Base class used to parse and convert arguments.
84
+
85
+ The :meth:`parse` method checks to make sure that the string argument is a
86
+ legal value and convert it to a native type. If the value cannot be
87
+ converted, it should throw a ``ValueError`` exception with a human
88
+ readable explanation of why the value is illegal.
89
+
90
+ Subclasses should also define a syntactic_help string which may be
91
+ presented to the user to describe the form of the legal values.
92
+
93
+ Argument parser classes must be stateless, since instances are cached
94
+ and shared between flags. Initializer arguments are allowed, but all
95
+ member variables must be derived from initializer arguments only.
96
+ """
97
+
98
+ syntactic_help: Text = ''
99
+
100
+ def parse(self, argument: Text) -> Optional[_T]:
101
+ """Parses the string argument and returns the native value.
102
+
103
+ By default it returns its argument unmodified.
104
+
105
+ Args:
106
+ argument: string argument passed in the commandline.
107
+
108
+ Raises:
109
+ ValueError: Raised when it fails to parse the argument.
110
+ TypeError: Raised when the argument has the wrong type.
111
+
112
+ Returns:
113
+ The parsed value in native type.
114
+ """
115
+ if not isinstance(argument, str):
116
+ raise TypeError('flag value must be a string, found "{}"'.format(
117
+ type(argument)))
118
+ return argument
119
+
120
+ def flag_type(self) -> Text:
121
+ """Returns a string representing the type of the flag."""
122
+ return 'string'
123
+
124
+ def _custom_xml_dom_elements(
125
+ self, doc: minidom.Document
126
+ ) -> List[minidom.Element]:
127
+ """Returns a list of minidom.Element to add additional flag information.
128
+
129
+ Args:
130
+ doc: minidom.Document, the DOM document it should create nodes from.
131
+ """
132
+ del doc # Unused.
133
+ return []
134
+
135
+
136
+ class ArgumentSerializer(Generic[_T]):
137
+ """Base class for generating string representations of a flag value."""
138
+
139
+ def serialize(self, value: _T) -> Text:
140
+ """Returns a serialized string of the value."""
141
+ return str(value)
142
+
143
+
144
+ class NumericParser(ArgumentParser[_N]):
145
+ """Parser of numeric values.
146
+
147
+ Parsed value may be bounded to a given upper and lower bound.
148
+ """
149
+
150
+ lower_bound: Optional[_N]
151
+ upper_bound: Optional[_N]
152
+
153
+ def is_outside_bounds(self, val: _N) -> bool:
154
+ """Returns whether the value is outside the bounds or not."""
155
+ return ((self.lower_bound is not None and val < self.lower_bound) or
156
+ (self.upper_bound is not None and val > self.upper_bound))
157
+
158
+ def parse(self, argument: Text) -> _N:
159
+ """See base class."""
160
+ val = self.convert(argument)
161
+ if self.is_outside_bounds(val):
162
+ raise ValueError('%s is not %s' % (val, self.syntactic_help))
163
+ return val
164
+
165
+ def _custom_xml_dom_elements(
166
+ self, doc: minidom.Document
167
+ ) -> List[minidom.Element]:
168
+ elements = []
169
+ if self.lower_bound is not None:
170
+ elements.append(_helpers.create_xml_dom_element(
171
+ doc, 'lower_bound', self.lower_bound))
172
+ if self.upper_bound is not None:
173
+ elements.append(_helpers.create_xml_dom_element(
174
+ doc, 'upper_bound', self.upper_bound))
175
+ return elements
176
+
177
+ def convert(self, argument: Text) -> _N:
178
+ """Returns the correct numeric value of argument.
179
+
180
+ Subclass must implement this method, and raise TypeError if argument is not
181
+ string or has the right numeric type.
182
+
183
+ Args:
184
+ argument: string argument passed in the commandline, or the numeric type.
185
+
186
+ Raises:
187
+ TypeError: Raised when argument is not a string or the right numeric type.
188
+ ValueError: Raised when failed to convert argument to the numeric value.
189
+ """
190
+ raise NotImplementedError
191
+
192
+
193
+ class FloatParser(NumericParser[float]):
194
+ """Parser of floating point values.
195
+
196
+ Parsed value may be bounded to a given upper and lower bound.
197
+ """
198
+ number_article = 'a'
199
+ number_name = 'number'
200
+ syntactic_help = ' '.join((number_article, number_name))
201
+
202
+ def __init__(
203
+ self,
204
+ lower_bound: Optional[float] = None,
205
+ upper_bound: Optional[float] = None,
206
+ ) -> None:
207
+ super(FloatParser, self).__init__()
208
+ self.lower_bound = lower_bound
209
+ self.upper_bound = upper_bound
210
+ sh = self.syntactic_help
211
+ if lower_bound is not None and upper_bound is not None:
212
+ sh = ('%s in the range [%s, %s]' % (sh, lower_bound, upper_bound))
213
+ elif lower_bound == 0:
214
+ sh = 'a non-negative %s' % self.number_name
215
+ elif upper_bound == 0:
216
+ sh = 'a non-positive %s' % self.number_name
217
+ elif upper_bound is not None:
218
+ sh = '%s <= %s' % (self.number_name, upper_bound)
219
+ elif lower_bound is not None:
220
+ sh = '%s >= %s' % (self.number_name, lower_bound)
221
+ self.syntactic_help = sh
222
+
223
+ def convert(self, argument: Union[int, float, str]) -> float:
224
+ """Returns the float value of argument."""
225
+ if (_is_integer_type(argument) or isinstance(argument, float) or
226
+ isinstance(argument, str)):
227
+ return float(argument)
228
+ else:
229
+ raise TypeError(
230
+ 'Expect argument to be a string, int, or float, found {}'.format(
231
+ type(argument)))
232
+
233
+ def flag_type(self) -> Text:
234
+ """See base class."""
235
+ return 'float'
236
+
237
+
238
+ class IntegerParser(NumericParser[int]):
239
+ """Parser of an integer value.
240
+
241
+ Parsed value may be bounded to a given upper and lower bound.
242
+ """
243
+ number_article = 'an'
244
+ number_name = 'integer'
245
+ syntactic_help = ' '.join((number_article, number_name))
246
+
247
+ def __init__(
248
+ self, lower_bound: Optional[int] = None, upper_bound: Optional[int] = None
249
+ ) -> None:
250
+ super(IntegerParser, self).__init__()
251
+ self.lower_bound = lower_bound
252
+ self.upper_bound = upper_bound
253
+ sh = self.syntactic_help
254
+ if lower_bound is not None and upper_bound is not None:
255
+ sh = ('%s in the range [%s, %s]' % (sh, lower_bound, upper_bound))
256
+ elif lower_bound == 1:
257
+ sh = 'a positive %s' % self.number_name
258
+ elif upper_bound == -1:
259
+ sh = 'a negative %s' % self.number_name
260
+ elif lower_bound == 0:
261
+ sh = 'a non-negative %s' % self.number_name
262
+ elif upper_bound == 0:
263
+ sh = 'a non-positive %s' % self.number_name
264
+ elif upper_bound is not None:
265
+ sh = '%s <= %s' % (self.number_name, upper_bound)
266
+ elif lower_bound is not None:
267
+ sh = '%s >= %s' % (self.number_name, lower_bound)
268
+ self.syntactic_help = sh
269
+
270
+ def convert(self, argument: Union[int, Text]) -> int:
271
+ """Returns the int value of argument."""
272
+ if _is_integer_type(argument):
273
+ return argument
274
+ elif isinstance(argument, str):
275
+ base = 10
276
+ if len(argument) > 2 and argument[0] == '0':
277
+ if argument[1] == 'o':
278
+ base = 8
279
+ elif argument[1] == 'x':
280
+ base = 16
281
+ return int(argument, base)
282
+ else:
283
+ raise TypeError('Expect argument to be a string or int, found {}'.format(
284
+ type(argument)))
285
+
286
+ def flag_type(self) -> Text:
287
+ """See base class."""
288
+ return 'int'
289
+
290
+
291
+ class BooleanParser(ArgumentParser[bool]):
292
+ """Parser of boolean values."""
293
+
294
+ def parse(self, argument: Union[Text, int]) -> bool:
295
+ """See base class."""
296
+ if isinstance(argument, str):
297
+ if argument.lower() in ('true', 't', '1'):
298
+ return True
299
+ elif argument.lower() in ('false', 'f', '0'):
300
+ return False
301
+ else:
302
+ raise ValueError('Non-boolean argument to boolean flag', argument)
303
+ elif isinstance(argument, int):
304
+ # Only allow bool or integer 0, 1.
305
+ # Note that float 1.0 == True, 0.0 == False.
306
+ bool_value = bool(argument)
307
+ if argument == bool_value:
308
+ return bool_value
309
+ else:
310
+ raise ValueError('Non-boolean argument to boolean flag', argument)
311
+
312
+ raise TypeError('Non-boolean argument to boolean flag', argument)
313
+
314
+ def flag_type(self) -> Text:
315
+ """See base class."""
316
+ return 'bool'
317
+
318
+
319
+ class EnumParser(ArgumentParser[Text]):
320
+ """Parser of a string enum value (a string value from a given set)."""
321
+
322
+ def __init__(
323
+ self, enum_values: Iterable[Text], case_sensitive: bool = True
324
+ ) -> None:
325
+ """Initializes EnumParser.
326
+
327
+ Args:
328
+ enum_values: [str], a non-empty list of string values in the enum.
329
+ case_sensitive: bool, whether or not the enum is to be case-sensitive.
330
+
331
+ Raises:
332
+ ValueError: When enum_values is empty.
333
+ """
334
+ if not enum_values:
335
+ raise ValueError(
336
+ 'enum_values cannot be empty, found "{}"'.format(enum_values))
337
+ if isinstance(enum_values, str):
338
+ raise ValueError(
339
+ 'enum_values cannot be a str, found "{}"'.format(enum_values)
340
+ )
341
+ super(EnumParser, self).__init__()
342
+ self.enum_values = list(enum_values)
343
+ self.case_sensitive = case_sensitive
344
+
345
+ def parse(self, argument: Text) -> Text:
346
+ """Determines validity of argument and returns the correct element of enum.
347
+
348
+ Args:
349
+ argument: str, the supplied flag value.
350
+
351
+ Returns:
352
+ The first matching element from enum_values.
353
+
354
+ Raises:
355
+ ValueError: Raised when argument didn't match anything in enum.
356
+ """
357
+ if self.case_sensitive:
358
+ if argument not in self.enum_values:
359
+ raise ValueError('value should be one of <%s>' %
360
+ '|'.join(self.enum_values))
361
+ else:
362
+ return argument
363
+ else:
364
+ if argument.upper() not in [value.upper() for value in self.enum_values]:
365
+ raise ValueError('value should be one of <%s>' %
366
+ '|'.join(self.enum_values))
367
+ else:
368
+ return [value for value in self.enum_values
369
+ if value.upper() == argument.upper()][0]
370
+
371
+ def flag_type(self) -> Text:
372
+ """See base class."""
373
+ return 'string enum'
374
+
375
+
376
+ class EnumClassParser(ArgumentParser[_ET]):
377
+ """Parser of an Enum class member."""
378
+
379
+ def __init__(
380
+ self, enum_class: Type[_ET], case_sensitive: bool = True
381
+ ) -> None:
382
+ """Initializes EnumParser.
383
+
384
+ Args:
385
+ enum_class: class, the Enum class with all possible flag values.
386
+ case_sensitive: bool, whether or not the enum is to be case-sensitive. If
387
+ False, all member names must be unique when case is ignored.
388
+
389
+ Raises:
390
+ TypeError: When enum_class is not a subclass of Enum.
391
+ ValueError: When enum_class is empty.
392
+ """
393
+ if not issubclass(enum_class, enum.Enum):
394
+ raise TypeError('{} is not a subclass of Enum.'.format(enum_class))
395
+ if not enum_class.__members__:
396
+ raise ValueError('enum_class cannot be empty, but "{}" is empty.'
397
+ .format(enum_class))
398
+ if not case_sensitive:
399
+ members = collections.Counter(
400
+ name.lower() for name in enum_class.__members__)
401
+ duplicate_keys = {
402
+ member for member, count in members.items() if count > 1
403
+ }
404
+ if duplicate_keys:
405
+ raise ValueError(
406
+ 'Duplicate enum values for {} using case_sensitive=False'.format(
407
+ duplicate_keys))
408
+
409
+ super(EnumClassParser, self).__init__()
410
+ self.enum_class = enum_class
411
+ self._case_sensitive = case_sensitive
412
+ if case_sensitive:
413
+ self._member_names = tuple(enum_class.__members__)
414
+ else:
415
+ self._member_names = tuple(
416
+ name.lower() for name in enum_class.__members__)
417
+
418
+ @property
419
+ def member_names(self) -> Sequence[Text]:
420
+ """The accepted enum names, in lowercase if not case sensitive."""
421
+ return self._member_names
422
+
423
+ def parse(self, argument: Union[_ET, Text]) -> _ET:
424
+ """Determines validity of argument and returns the correct element of enum.
425
+
426
+ Args:
427
+ argument: str or Enum class member, the supplied flag value.
428
+
429
+ Returns:
430
+ The first matching Enum class member in Enum class.
431
+
432
+ Raises:
433
+ ValueError: Raised when argument didn't match anything in enum.
434
+ """
435
+ if isinstance(argument, self.enum_class):
436
+ return argument # pytype: disable=bad-return-type
437
+ elif not isinstance(argument, str):
438
+ raise ValueError(
439
+ '{} is not an enum member or a name of a member in {}'.format(
440
+ argument, self.enum_class))
441
+ key = EnumParser(
442
+ self._member_names, case_sensitive=self._case_sensitive).parse(argument)
443
+ if self._case_sensitive:
444
+ return self.enum_class[key]
445
+ else:
446
+ # If EnumParser.parse() return a value, we're guaranteed to find it
447
+ # as a member of the class
448
+ return next(value for name, value in self.enum_class.__members__.items()
449
+ if name.lower() == key.lower())
450
+
451
+ def flag_type(self) -> Text:
452
+ """See base class."""
453
+ return 'enum class'
454
+
455
+
456
+ class ListSerializer(Generic[_T], ArgumentSerializer[List[_T]]):
457
+
458
+ def __init__(self, list_sep: Text) -> None:
459
+ self.list_sep = list_sep
460
+
461
+ def serialize(self, value: List[_T]) -> Text:
462
+ """See base class."""
463
+ return self.list_sep.join([str(x) for x in value])
464
+
465
+
466
+ class EnumClassListSerializer(ListSerializer[_ET]):
467
+ """A serializer for :class:`MultiEnumClass` flags.
468
+
469
+ This serializer simply joins the output of `EnumClassSerializer` using a
470
+ provided separator.
471
+ """
472
+
473
+ def __init__(self, list_sep: Text, **kwargs) -> None:
474
+ """Initializes EnumClassListSerializer.
475
+
476
+ Args:
477
+ list_sep: String to be used as a separator when serializing
478
+ **kwargs: Keyword arguments to the `EnumClassSerializer` used to serialize
479
+ individual values.
480
+ """
481
+ super(EnumClassListSerializer, self).__init__(list_sep)
482
+ self._element_serializer = EnumClassSerializer(**kwargs)
483
+
484
+ def serialize(self, value: Union[_ET, List[_ET]]) -> Text:
485
+ """See base class."""
486
+ if isinstance(value, list):
487
+ return self.list_sep.join(
488
+ self._element_serializer.serialize(x) for x in value)
489
+ else:
490
+ return self._element_serializer.serialize(value)
491
+
492
+
493
+ class CsvListSerializer(ListSerializer[Text]):
494
+
495
+ def serialize(self, value: List[Text]) -> Text:
496
+ """Serializes a list as a CSV string or unicode."""
497
+ output = io.StringIO()
498
+ writer = csv.writer(output, delimiter=self.list_sep)
499
+ writer.writerow([str(x) for x in value])
500
+ serialized_value = output.getvalue().strip()
501
+
502
+ # We need the returned value to be pure ascii or Unicodes so that
503
+ # when the xml help is generated they are usefully encodable.
504
+ return str(serialized_value)
505
+
506
+
507
+ class EnumClassSerializer(ArgumentSerializer[_ET]):
508
+ """Class for generating string representations of an enum class flag value."""
509
+
510
+ def __init__(self, lowercase: bool) -> None:
511
+ """Initializes EnumClassSerializer.
512
+
513
+ Args:
514
+ lowercase: If True, enum member names are lowercased during serialization.
515
+ """
516
+ self._lowercase = lowercase
517
+
518
+ def serialize(self, value: _ET) -> Text:
519
+ """Returns a serialized string of the Enum class value."""
520
+ as_string = str(value.name)
521
+ return as_string.lower() if self._lowercase else as_string
522
+
523
+
524
+ class BaseListParser(ArgumentParser):
525
+ """Base class for a parser of lists of strings.
526
+
527
+ To extend, inherit from this class; from the subclass ``__init__``, call::
528
+
529
+ super().__init__(token, name)
530
+
531
+ where token is a character used to tokenize, and name is a description
532
+ of the separator.
533
+ """
534
+
535
+ def __init__(
536
+ self, token: Optional[Text] = None, name: Optional[Text] = None
537
+ ) -> None:
538
+ assert name
539
+ super(BaseListParser, self).__init__()
540
+ self._token = token
541
+ self._name = name
542
+ self.syntactic_help = 'a %s separated list' % self._name
543
+
544
+ def parse(self, argument: Text) -> List[Text]:
545
+ """See base class."""
546
+ if isinstance(argument, list):
547
+ return argument
548
+ elif not argument:
549
+ return []
550
+ else:
551
+ return [s.strip() for s in argument.split(self._token)]
552
+
553
+ def flag_type(self) -> Text:
554
+ """See base class."""
555
+ return '%s separated list of strings' % self._name
556
+
557
+
558
+ class ListParser(BaseListParser):
559
+ """Parser for a comma-separated list of strings."""
560
+
561
+ def __init__(self) -> None:
562
+ super(ListParser, self).__init__(',', 'comma')
563
+
564
+ def parse(self, argument: Union[Text, List[Text]]) -> List[Text]:
565
+ """Parses argument as comma-separated list of strings."""
566
+ if isinstance(argument, list):
567
+ return argument
568
+ elif not argument:
569
+ return []
570
+ else:
571
+ try:
572
+ return [s.strip() for s in list(csv.reader([argument], strict=True))[0]]
573
+ except csv.Error as e:
574
+ # Provide a helpful report for case like
575
+ # --listflag="$(printf 'hello,\nworld')"
576
+ # IOW, list flag values containing naked newlines. This error
577
+ # was previously "reported" by allowing csv.Error to
578
+ # propagate.
579
+ raise ValueError('Unable to parse the value %r as a %s: %s'
580
+ % (argument, self.flag_type(), e))
581
+
582
+ def _custom_xml_dom_elements(
583
+ self, doc: minidom.Document
584
+ ) -> List[minidom.Element]:
585
+ elements = super(ListParser, self)._custom_xml_dom_elements(doc)
586
+ elements.append(_helpers.create_xml_dom_element(
587
+ doc, 'list_separator', repr(',')))
588
+ return elements
589
+
590
+
591
+ class WhitespaceSeparatedListParser(BaseListParser):
592
+ """Parser for a whitespace-separated list of strings."""
593
+
594
+ def __init__(self, comma_compat: bool = False) -> None:
595
+ """Initializer.
596
+
597
+ Args:
598
+ comma_compat: bool, whether to support comma as an additional separator.
599
+ If False then only whitespace is supported. This is intended only for
600
+ backwards compatibility with flags that used to be comma-separated.
601
+ """
602
+ self._comma_compat = comma_compat
603
+ name = 'whitespace or comma' if self._comma_compat else 'whitespace'
604
+ super(WhitespaceSeparatedListParser, self).__init__(None, name)
605
+
606
+ def parse(self, argument: Union[Text, List[Text]]) -> List[Text]:
607
+ """Parses argument as whitespace-separated list of strings.
608
+
609
+ It also parses argument as comma-separated list of strings if requested.
610
+
611
+ Args:
612
+ argument: string argument passed in the commandline.
613
+
614
+ Returns:
615
+ [str], the parsed flag value.
616
+ """
617
+ if isinstance(argument, list):
618
+ return argument
619
+ elif not argument:
620
+ return []
621
+ else:
622
+ if self._comma_compat:
623
+ argument = argument.replace(',', ' ')
624
+ return argument.split()
625
+
626
+ def _custom_xml_dom_elements(
627
+ self, doc: minidom.Document
628
+ ) -> List[minidom.Element]:
629
+ elements = super(WhitespaceSeparatedListParser, self
630
+ )._custom_xml_dom_elements(doc)
631
+ separators = list(string.whitespace)
632
+ if self._comma_compat:
633
+ separators.append(',')
634
+ separators.sort()
635
+ for sep_char in separators:
636
+ elements.append(_helpers.create_xml_dom_element(
637
+ doc, 'list_separator', repr(sep_char)))
638
+ return elements
MLPY/Lib/site-packages/absl/flags/_defines.py ADDED
@@ -0,0 +1,1686 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2017 The Abseil Authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """This modules contains flags DEFINE functions.
15
+
16
+ Do NOT import this module directly. Import the flags package and use the
17
+ aliases defined at the package level instead.
18
+ """
19
+
20
+ import enum
21
+ import sys
22
+ import types
23
+ import typing
24
+ from typing import Text, List, Any, TypeVar, Optional, Union, Type, Iterable, overload
25
+
26
+ from absl.flags import _argument_parser
27
+ from absl.flags import _exceptions
28
+ from absl.flags import _flag
29
+ from absl.flags import _flagvalues
30
+ from absl.flags import _helpers
31
+ from absl.flags import _validators
32
+
33
+ _helpers.disclaim_module_ids.add(id(sys.modules[__name__]))
34
+
35
+ _T = TypeVar('_T')
36
+ _ET = TypeVar('_ET', bound=enum.Enum)
37
+
38
+
39
+ def _register_bounds_validator_if_needed(parser, name, flag_values):
40
+ """Enforces lower and upper bounds for numeric flags.
41
+
42
+ Args:
43
+ parser: NumericParser (either FloatParser or IntegerParser), provides lower
44
+ and upper bounds, and help text to display.
45
+ name: str, name of the flag
46
+ flag_values: FlagValues.
47
+ """
48
+ if parser.lower_bound is not None or parser.upper_bound is not None:
49
+
50
+ def checker(value):
51
+ if value is not None and parser.is_outside_bounds(value):
52
+ message = '%s is not %s' % (value, parser.syntactic_help)
53
+ raise _exceptions.ValidationError(message)
54
+ return True
55
+
56
+ _validators.register_validator(name, checker, flag_values=flag_values)
57
+
58
+
59
+ @overload
60
+ def DEFINE( # pylint: disable=invalid-name
61
+ parser: _argument_parser.ArgumentParser[_T],
62
+ name: Text,
63
+ default: Any,
64
+ help: Optional[Text], # pylint: disable=redefined-builtin
65
+ flag_values: _flagvalues.FlagValues = ...,
66
+ serializer: Optional[_argument_parser.ArgumentSerializer[_T]] = ...,
67
+ module_name: Optional[Text] = ...,
68
+ required: 'typing.Literal[True]' = ...,
69
+ **args: Any
70
+ ) -> _flagvalues.FlagHolder[_T]:
71
+ ...
72
+
73
+
74
+ @overload
75
+ def DEFINE( # pylint: disable=invalid-name
76
+ parser: _argument_parser.ArgumentParser[_T],
77
+ name: Text,
78
+ default: Optional[Any],
79
+ help: Optional[Text], # pylint: disable=redefined-builtin
80
+ flag_values: _flagvalues.FlagValues = ...,
81
+ serializer: Optional[_argument_parser.ArgumentSerializer[_T]] = ...,
82
+ module_name: Optional[Text] = ...,
83
+ required: bool = ...,
84
+ **args: Any
85
+ ) -> _flagvalues.FlagHolder[Optional[_T]]:
86
+ ...
87
+
88
+
89
+ def DEFINE( # pylint: disable=invalid-name
90
+ parser,
91
+ name,
92
+ default,
93
+ help, # pylint: disable=redefined-builtin
94
+ flag_values=_flagvalues.FLAGS,
95
+ serializer=None,
96
+ module_name=None,
97
+ required=False,
98
+ **args):
99
+ """Registers a generic Flag object.
100
+
101
+ NOTE: in the docstrings of all DEFINE* functions, "registers" is short
102
+ for "creates a new flag and registers it".
103
+
104
+ Auxiliary function: clients should use the specialized ``DEFINE_<type>``
105
+ function instead.
106
+
107
+ Args:
108
+ parser: :class:`ArgumentParser`, used to parse the flag arguments.
109
+ name: str, the flag name.
110
+ default: The default value of the flag.
111
+ help: str, the help message.
112
+ flag_values: :class:`FlagValues`, the FlagValues instance with which the
113
+ flag will be registered. This should almost never need to be overridden.
114
+ serializer: :class:`ArgumentSerializer`, the flag serializer instance.
115
+ module_name: str, the name of the Python module declaring this flag. If not
116
+ provided, it will be computed using the stack trace of this call.
117
+ required: bool, is this a required flag. This must be used as a keyword
118
+ argument.
119
+ **args: dict, the extra keyword args that are passed to ``Flag.__init__``.
120
+
121
+ Returns:
122
+ a handle to defined flag.
123
+ """
124
+ return DEFINE_flag(
125
+ _flag.Flag(parser, serializer, name, default, help, **args),
126
+ flag_values,
127
+ module_name,
128
+ required=True if required else False,
129
+ )
130
+
131
+
132
+ @overload
133
+ def DEFINE_flag( # pylint: disable=invalid-name
134
+ flag: _flag.Flag[_T],
135
+ flag_values: _flagvalues.FlagValues = ...,
136
+ module_name: Optional[Text] = ...,
137
+ required: 'typing.Literal[True]' = ...,
138
+ ) -> _flagvalues.FlagHolder[_T]:
139
+ ...
140
+
141
+
142
+ @overload
143
+ def DEFINE_flag( # pylint: disable=invalid-name
144
+ flag: _flag.Flag[_T],
145
+ flag_values: _flagvalues.FlagValues = ...,
146
+ module_name: Optional[Text] = ...,
147
+ required: bool = ...,
148
+ ) -> _flagvalues.FlagHolder[Optional[_T]]:
149
+ ...
150
+
151
+
152
+ def DEFINE_flag( # pylint: disable=invalid-name
153
+ flag,
154
+ flag_values=_flagvalues.FLAGS,
155
+ module_name=None,
156
+ required=False):
157
+ """Registers a :class:`Flag` object with a :class:`FlagValues` object.
158
+
159
+ By default, the global :const:`FLAGS` ``FlagValue`` object is used.
160
+
161
+ Typical users will use one of the more specialized DEFINE_xxx
162
+ functions, such as :func:`DEFINE_string` or :func:`DEFINE_integer`. But
163
+ developers who need to create :class:`Flag` objects themselves should use
164
+ this function to register their flags.
165
+
166
+ Args:
167
+ flag: :class:`Flag`, a flag that is key to the module.
168
+ flag_values: :class:`FlagValues`, the ``FlagValues`` instance with which the
169
+ flag will be registered. This should almost never need to be overridden.
170
+ module_name: str, the name of the Python module declaring this flag. If not
171
+ provided, it will be computed using the stack trace of this call.
172
+ required: bool, is this a required flag. This must be used as a keyword
173
+ argument.
174
+
175
+ Returns:
176
+ a handle to defined flag.
177
+ """
178
+ if required and flag.default is not None:
179
+ raise ValueError('Required flag --%s cannot have a non-None default' %
180
+ flag.name)
181
+ # Copying the reference to flag_values prevents pychecker warnings.
182
+ fv = flag_values
183
+ fv[flag.name] = flag
184
+ # Tell flag_values who's defining the flag.
185
+ if module_name:
186
+ module = sys.modules.get(module_name)
187
+ else:
188
+ module, module_name = _helpers.get_calling_module_object_and_name()
189
+ flag_values.register_flag_by_module(module_name, flag)
190
+ flag_values.register_flag_by_module_id(id(module), flag)
191
+ if required:
192
+ _validators.mark_flag_as_required(flag.name, fv)
193
+ ensure_non_none_value = (flag.default is not None) or required
194
+ return _flagvalues.FlagHolder(
195
+ fv, flag, ensure_non_none_value=ensure_non_none_value)
196
+
197
+
198
+ def set_default(flag_holder: _flagvalues.FlagHolder[_T], value: _T) -> None:
199
+ """Changes the default value of the provided flag object.
200
+
201
+ The flag's current value is also updated if the flag is currently using
202
+ the default value, i.e. not specified in the command line, and not set
203
+ by FLAGS.name = value.
204
+
205
+ Args:
206
+ flag_holder: FlagHolder, the flag to modify.
207
+ value: The new default value.
208
+
209
+ Raises:
210
+ IllegalFlagValueError: Raised when value is not valid.
211
+ """
212
+ flag_holder._flagvalues.set_default(flag_holder.name, value) # pylint: disable=protected-access
213
+
214
+
215
+ def override_value(flag_holder: _flagvalues.FlagHolder[_T], value: _T) -> None:
216
+ """Overrides the value of the provided flag.
217
+
218
+ This value takes precedent over the default value and, when called after flag
219
+ parsing, any value provided at the command line.
220
+
221
+ Args:
222
+ flag_holder: FlagHolder, the flag to modify.
223
+ value: The new value.
224
+
225
+ Raises:
226
+ IllegalFlagValueError: The value did not pass the flag parser or validators.
227
+ """
228
+ fv = flag_holder._flagvalues # pylint: disable=protected-access
229
+ # Ensure the new value satisfies the flag's parser while avoiding side
230
+ # effects of calling parse().
231
+ parsed = fv[flag_holder.name]._parse(value) # pylint: disable=protected-access
232
+ if parsed != value:
233
+ raise _exceptions.IllegalFlagValueError(
234
+ 'flag %s: parsed value %r not equal to original %r'
235
+ % (flag_holder.name, parsed, value)
236
+ )
237
+ setattr(fv, flag_holder.name, value)
238
+
239
+
240
+ def _internal_declare_key_flags(
241
+ flag_names: List[str],
242
+ flag_values: _flagvalues.FlagValues = _flagvalues.FLAGS,
243
+ key_flag_values: Optional[_flagvalues.FlagValues] = None,
244
+ ) -> None:
245
+ """Declares a flag as key for the calling module.
246
+
247
+ Internal function. User code should call declare_key_flag or
248
+ adopt_module_key_flags instead.
249
+
250
+ Args:
251
+ flag_names: [str], a list of names of already-registered Flag objects.
252
+ flag_values: :class:`FlagValues`, the FlagValues instance with which the
253
+ flags listed in flag_names have registered (the value of the flag_values
254
+ argument from the ``DEFINE_*`` calls that defined those flags). This
255
+ should almost never need to be overridden.
256
+ key_flag_values: :class:`FlagValues`, the FlagValues instance that (among
257
+ possibly many other things) keeps track of the key flags for each module.
258
+ Default ``None`` means "same as flag_values". This should almost never
259
+ need to be overridden.
260
+
261
+ Raises:
262
+ UnrecognizedFlagError: Raised when the flag is not defined.
263
+ """
264
+ key_flag_values = key_flag_values or flag_values
265
+
266
+ module = _helpers.get_calling_module()
267
+
268
+ for flag_name in flag_names:
269
+ key_flag_values.register_key_flag_for_module(module, flag_values[flag_name])
270
+
271
+
272
+ def declare_key_flag(
273
+ flag_name: Union[Text, _flagvalues.FlagHolder],
274
+ flag_values: _flagvalues.FlagValues = _flagvalues.FLAGS,
275
+ ) -> None:
276
+ """Declares one flag as key to the current module.
277
+
278
+ Key flags are flags that are deemed really important for a module.
279
+ They are important when listing help messages; e.g., if the
280
+ --helpshort command-line flag is used, then only the key flags of the
281
+ main module are listed (instead of all flags, as in the case of
282
+ --helpfull).
283
+
284
+ Sample usage::
285
+
286
+ flags.declare_key_flag('flag_1')
287
+
288
+ Args:
289
+ flag_name: str | :class:`FlagHolder`, the name or holder of an already
290
+ declared flag. (Redeclaring flags as key, including flags implicitly key
291
+ because they were declared in this module, is a no-op.)
292
+ Positional-only parameter.
293
+ flag_values: :class:`FlagValues`, the FlagValues instance in which the
294
+ flag will be declared as a key flag. This should almost never need to be
295
+ overridden.
296
+
297
+ Raises:
298
+ ValueError: Raised if flag_name not defined as a Python flag.
299
+ """
300
+ flag_name, flag_values = _flagvalues.resolve_flag_ref(flag_name, flag_values)
301
+ if flag_name in _helpers.SPECIAL_FLAGS:
302
+ # Take care of the special flags, e.g., --flagfile, --undefok.
303
+ # These flags are defined in SPECIAL_FLAGS, and are treated
304
+ # specially during flag parsing, taking precedence over the
305
+ # user-defined flags.
306
+ _internal_declare_key_flags([flag_name],
307
+ flag_values=_helpers.SPECIAL_FLAGS,
308
+ key_flag_values=flag_values)
309
+ return
310
+ try:
311
+ _internal_declare_key_flags([flag_name], flag_values=flag_values)
312
+ except KeyError:
313
+ raise ValueError('Flag --%s is undefined. To set a flag as a key flag '
314
+ 'first define it in Python.' % flag_name)
315
+
316
+
317
+ def adopt_module_key_flags(
318
+ module: Any, flag_values: _flagvalues.FlagValues = _flagvalues.FLAGS
319
+ ) -> None:
320
+ """Declares that all flags key to a module are key to the current module.
321
+
322
+ Args:
323
+ module: module, the module object from which all key flags will be declared
324
+ as key flags to the current module.
325
+ flag_values: :class:`FlagValues`, the FlagValues instance in which the
326
+ flags will be declared as key flags. This should almost never need to be
327
+ overridden.
328
+
329
+ Raises:
330
+ Error: Raised when given an argument that is a module name (a string),
331
+ instead of a module object.
332
+ """
333
+ if not isinstance(module, types.ModuleType):
334
+ raise _exceptions.Error('Expected a module object, not %r.' % (module,))
335
+ _internal_declare_key_flags(
336
+ [f.name for f in flag_values.get_key_flags_for_module(module.__name__)],
337
+ flag_values=flag_values)
338
+ # If module is this flag module, take _helpers.SPECIAL_FLAGS into account.
339
+ if module == _helpers.FLAGS_MODULE:
340
+ _internal_declare_key_flags(
341
+ # As we associate flags with get_calling_module_object_and_name(), the
342
+ # special flags defined in this module are incorrectly registered with
343
+ # a different module. So, we can't use get_key_flags_for_module.
344
+ # Instead, we take all flags from _helpers.SPECIAL_FLAGS (a private
345
+ # FlagValues, where no other module should register flags).
346
+ [_helpers.SPECIAL_FLAGS[name].name for name in _helpers.SPECIAL_FLAGS],
347
+ flag_values=_helpers.SPECIAL_FLAGS,
348
+ key_flag_values=flag_values)
349
+
350
+
351
+ def disclaim_key_flags() -> None:
352
+ """Declares that the current module will not define any more key flags.
353
+
354
+ Normally, the module that calls the DEFINE_xxx functions claims the
355
+ flag to be its key flag. This is undesirable for modules that
356
+ define additional DEFINE_yyy functions with its own flag parsers and
357
+ serializers, since that module will accidentally claim flags defined
358
+ by DEFINE_yyy as its key flags. After calling this function, the
359
+ module disclaims flag definitions thereafter, so the key flags will
360
+ be correctly attributed to the caller of DEFINE_yyy.
361
+
362
+ After calling this function, the module will not be able to define
363
+ any more flags. This function will affect all FlagValues objects.
364
+ """
365
+ globals_for_caller = sys._getframe(1).f_globals # pylint: disable=protected-access
366
+ module, _ = _helpers.get_module_object_and_name(globals_for_caller)
367
+ _helpers.disclaim_module_ids.add(id(module))
368
+
369
+
370
+ @overload
371
+ def DEFINE_string( # pylint: disable=invalid-name
372
+ name: Text,
373
+ default: Optional[Text],
374
+ help: Optional[Text], # pylint: disable=redefined-builtin
375
+ flag_values: _flagvalues.FlagValues = ...,
376
+ *,
377
+ required: 'typing.Literal[True]',
378
+ **args: Any
379
+ ) -> _flagvalues.FlagHolder[Text]:
380
+ ...
381
+
382
+
383
+ @overload
384
+ def DEFINE_string( # pylint: disable=invalid-name
385
+ name: Text,
386
+ default: None,
387
+ help: Optional[Text], # pylint: disable=redefined-builtin
388
+ flag_values: _flagvalues.FlagValues = ...,
389
+ required: bool = ...,
390
+ **args: Any
391
+ ) -> _flagvalues.FlagHolder[Optional[Text]]:
392
+ ...
393
+
394
+
395
+ @overload
396
+ def DEFINE_string( # pylint: disable=invalid-name
397
+ name: Text,
398
+ default: Text,
399
+ help: Optional[Text], # pylint: disable=redefined-builtin
400
+ flag_values: _flagvalues.FlagValues = ...,
401
+ required: bool = ...,
402
+ **args: Any
403
+ ) -> _flagvalues.FlagHolder[Text]:
404
+ ...
405
+
406
+
407
+ def DEFINE_string( # pylint: disable=invalid-name,redefined-builtin
408
+ name,
409
+ default,
410
+ help,
411
+ flag_values=_flagvalues.FLAGS,
412
+ required=False,
413
+ **args):
414
+ """Registers a flag whose value can be any string."""
415
+ parser = _argument_parser.ArgumentParser[str]()
416
+ serializer = _argument_parser.ArgumentSerializer[str]()
417
+ return DEFINE(
418
+ parser,
419
+ name,
420
+ default,
421
+ help,
422
+ flag_values,
423
+ serializer,
424
+ required=True if required else False,
425
+ **args,
426
+ )
427
+
428
+
429
+ @overload
430
+ def DEFINE_boolean( # pylint: disable=invalid-name
431
+ name: Text,
432
+ default: Union[None, Text, bool, int],
433
+ help: Optional[Text], # pylint: disable=redefined-builtin
434
+ flag_values: _flagvalues.FlagValues = ...,
435
+ module_name: Optional[Text] = ...,
436
+ *,
437
+ required: 'typing.Literal[True]',
438
+ **args: Any
439
+ ) -> _flagvalues.FlagHolder[bool]:
440
+ ...
441
+
442
+
443
+ @overload
444
+ def DEFINE_boolean( # pylint: disable=invalid-name
445
+ name: Text,
446
+ default: None,
447
+ help: Optional[Text], # pylint: disable=redefined-builtin
448
+ flag_values: _flagvalues.FlagValues = ...,
449
+ module_name: Optional[Text] = ...,
450
+ required: bool = ...,
451
+ **args: Any
452
+ ) -> _flagvalues.FlagHolder[Optional[bool]]:
453
+ ...
454
+
455
+
456
+ @overload
457
+ def DEFINE_boolean( # pylint: disable=invalid-name
458
+ name: Text,
459
+ default: Union[Text, bool, int],
460
+ help: Optional[Text], # pylint: disable=redefined-builtin
461
+ flag_values: _flagvalues.FlagValues = ...,
462
+ module_name: Optional[Text] = ...,
463
+ required: bool = ...,
464
+ **args: Any
465
+ ) -> _flagvalues.FlagHolder[bool]:
466
+ ...
467
+
468
+
469
+ def DEFINE_boolean( # pylint: disable=invalid-name,redefined-builtin
470
+ name,
471
+ default,
472
+ help,
473
+ flag_values=_flagvalues.FLAGS,
474
+ module_name=None,
475
+ required=False,
476
+ **args):
477
+ """Registers a boolean flag.
478
+
479
+ Such a boolean flag does not take an argument. If a user wants to
480
+ specify a false value explicitly, the long option beginning with 'no'
481
+ must be used: i.e. --noflag
482
+
483
+ This flag will have a value of None, True or False. None is possible
484
+ if default=None and the user does not specify the flag on the command
485
+ line.
486
+
487
+ Args:
488
+ name: str, the flag name.
489
+ default: bool|str|None, the default value of the flag.
490
+ help: str, the help message.
491
+ flag_values: :class:`FlagValues`, the FlagValues instance with which the
492
+ flag will be registered. This should almost never need to be overridden.
493
+ module_name: str, the name of the Python module declaring this flag. If not
494
+ provided, it will be computed using the stack trace of this call.
495
+ required: bool, is this a required flag. This must be used as a keyword
496
+ argument.
497
+ **args: dict, the extra keyword args that are passed to ``Flag.__init__``.
498
+
499
+ Returns:
500
+ a handle to defined flag.
501
+ """
502
+ return DEFINE_flag(
503
+ _flag.BooleanFlag(name, default, help, **args),
504
+ flag_values,
505
+ module_name,
506
+ required=True if required else False,
507
+ )
508
+
509
+
510
+ @overload
511
+ def DEFINE_float( # pylint: disable=invalid-name
512
+ name: Text,
513
+ default: Union[None, float, Text],
514
+ help: Optional[Text], # pylint: disable=redefined-builtin
515
+ lower_bound: Optional[float] = ...,
516
+ upper_bound: Optional[float] = ...,
517
+ flag_values: _flagvalues.FlagValues = ...,
518
+ *,
519
+ required: 'typing.Literal[True]',
520
+ **args: Any
521
+ ) -> _flagvalues.FlagHolder[float]:
522
+ ...
523
+
524
+
525
+ @overload
526
+ def DEFINE_float( # pylint: disable=invalid-name
527
+ name: Text,
528
+ default: None,
529
+ help: Optional[Text], # pylint: disable=redefined-builtin
530
+ lower_bound: Optional[float] = ...,
531
+ upper_bound: Optional[float] = ...,
532
+ flag_values: _flagvalues.FlagValues = ...,
533
+ required: bool = ...,
534
+ **args: Any
535
+ ) -> _flagvalues.FlagHolder[Optional[float]]:
536
+ ...
537
+
538
+
539
+ @overload
540
+ def DEFINE_float( # pylint: disable=invalid-name
541
+ name: Text,
542
+ default: Union[float, Text],
543
+ help: Optional[Text], # pylint: disable=redefined-builtin
544
+ lower_bound: Optional[float] = ...,
545
+ upper_bound: Optional[float] = ...,
546
+ flag_values: _flagvalues.FlagValues = ...,
547
+ required: bool = ...,
548
+ **args: Any
549
+ ) -> _flagvalues.FlagHolder[float]:
550
+ ...
551
+
552
+
553
+ def DEFINE_float( # pylint: disable=invalid-name,redefined-builtin
554
+ name,
555
+ default,
556
+ help,
557
+ lower_bound=None,
558
+ upper_bound=None,
559
+ flag_values=_flagvalues.FLAGS,
560
+ required=False,
561
+ **args):
562
+ """Registers a flag whose value must be a float.
563
+
564
+ If ``lower_bound`` or ``upper_bound`` are set, then this flag must be
565
+ within the given range.
566
+
567
+ Args:
568
+ name: str, the flag name.
569
+ default: float|str|None, the default value of the flag.
570
+ help: str, the help message.
571
+ lower_bound: float, min value of the flag.
572
+ upper_bound: float, max value of the flag.
573
+ flag_values: :class:`FlagValues`, the FlagValues instance with which the
574
+ flag will be registered. This should almost never need to be overridden.
575
+ required: bool, is this a required flag. This must be used as a keyword
576
+ argument.
577
+ **args: dict, the extra keyword args that are passed to :func:`DEFINE`.
578
+
579
+ Returns:
580
+ a handle to defined flag.
581
+ """
582
+ parser = _argument_parser.FloatParser(lower_bound, upper_bound)
583
+ serializer = _argument_parser.ArgumentSerializer()
584
+ result = DEFINE(
585
+ parser,
586
+ name,
587
+ default,
588
+ help,
589
+ flag_values,
590
+ serializer,
591
+ required=True if required else False,
592
+ **args,
593
+ )
594
+ _register_bounds_validator_if_needed(parser, name, flag_values=flag_values)
595
+ return result
596
+
597
+
598
+ @overload
599
+ def DEFINE_integer( # pylint: disable=invalid-name
600
+ name: Text,
601
+ default: Union[None, int, Text],
602
+ help: Optional[Text], # pylint: disable=redefined-builtin
603
+ lower_bound: Optional[int] = ...,
604
+ upper_bound: Optional[int] = ...,
605
+ flag_values: _flagvalues.FlagValues = ...,
606
+ *,
607
+ required: 'typing.Literal[True]',
608
+ **args: Any
609
+ ) -> _flagvalues.FlagHolder[int]:
610
+ ...
611
+
612
+
613
+ @overload
614
+ def DEFINE_integer( # pylint: disable=invalid-name
615
+ name: Text,
616
+ default: None,
617
+ help: Optional[Text], # pylint: disable=redefined-builtin
618
+ lower_bound: Optional[int] = ...,
619
+ upper_bound: Optional[int] = ...,
620
+ flag_values: _flagvalues.FlagValues = ...,
621
+ required: bool = ...,
622
+ **args: Any
623
+ ) -> _flagvalues.FlagHolder[Optional[int]]:
624
+ ...
625
+
626
+
627
+ @overload
628
+ def DEFINE_integer( # pylint: disable=invalid-name
629
+ name: Text,
630
+ default: Union[int, Text],
631
+ help: Optional[Text], # pylint: disable=redefined-builtin
632
+ lower_bound: Optional[int] = ...,
633
+ upper_bound: Optional[int] = ...,
634
+ flag_values: _flagvalues.FlagValues = ...,
635
+ required: bool = ...,
636
+ **args: Any
637
+ ) -> _flagvalues.FlagHolder[int]:
638
+ ...
639
+
640
+
641
+ def DEFINE_integer( # pylint: disable=invalid-name,redefined-builtin
642
+ name,
643
+ default,
644
+ help,
645
+ lower_bound=None,
646
+ upper_bound=None,
647
+ flag_values=_flagvalues.FLAGS,
648
+ required=False,
649
+ **args):
650
+ """Registers a flag whose value must be an integer.
651
+
652
+ If ``lower_bound``, or ``upper_bound`` are set, then this flag must be
653
+ within the given range.
654
+
655
+ Args:
656
+ name: str, the flag name.
657
+ default: int|str|None, the default value of the flag.
658
+ help: str, the help message.
659
+ lower_bound: int, min value of the flag.
660
+ upper_bound: int, max value of the flag.
661
+ flag_values: :class:`FlagValues`, the FlagValues instance with which the
662
+ flag will be registered. This should almost never need to be overridden.
663
+ required: bool, is this a required flag. This must be used as a keyword
664
+ argument.
665
+ **args: dict, the extra keyword args that are passed to :func:`DEFINE`.
666
+
667
+ Returns:
668
+ a handle to defined flag.
669
+ """
670
+ parser = _argument_parser.IntegerParser(lower_bound, upper_bound)
671
+ serializer = _argument_parser.ArgumentSerializer()
672
+ result = DEFINE(
673
+ parser,
674
+ name,
675
+ default,
676
+ help,
677
+ flag_values,
678
+ serializer,
679
+ required=True if required else False,
680
+ **args,
681
+ )
682
+ _register_bounds_validator_if_needed(parser, name, flag_values=flag_values)
683
+ return result
684
+
685
+
686
+ @overload
687
+ def DEFINE_enum( # pylint: disable=invalid-name
688
+ name: Text,
689
+ default: Optional[Text],
690
+ enum_values: Iterable[Text],
691
+ help: Optional[Text], # pylint: disable=redefined-builtin
692
+ flag_values: _flagvalues.FlagValues = ...,
693
+ module_name: Optional[Text] = ...,
694
+ *,
695
+ required: 'typing.Literal[True]',
696
+ **args: Any
697
+ ) -> _flagvalues.FlagHolder[Text]:
698
+ ...
699
+
700
+
701
+ @overload
702
+ def DEFINE_enum( # pylint: disable=invalid-name
703
+ name: Text,
704
+ default: None,
705
+ enum_values: Iterable[Text],
706
+ help: Optional[Text], # pylint: disable=redefined-builtin
707
+ flag_values: _flagvalues.FlagValues = ...,
708
+ module_name: Optional[Text] = ...,
709
+ required: bool = ...,
710
+ **args: Any
711
+ ) -> _flagvalues.FlagHolder[Optional[Text]]:
712
+ ...
713
+
714
+
715
+ @overload
716
+ def DEFINE_enum( # pylint: disable=invalid-name
717
+ name: Text,
718
+ default: Text,
719
+ enum_values: Iterable[Text],
720
+ help: Optional[Text], # pylint: disable=redefined-builtin
721
+ flag_values: _flagvalues.FlagValues = ...,
722
+ module_name: Optional[Text] = ...,
723
+ required: bool = ...,
724
+ **args: Any
725
+ ) -> _flagvalues.FlagHolder[Text]:
726
+ ...
727
+
728
+
729
+ def DEFINE_enum( # pylint: disable=invalid-name,redefined-builtin
730
+ name,
731
+ default,
732
+ enum_values,
733
+ help,
734
+ flag_values=_flagvalues.FLAGS,
735
+ module_name=None,
736
+ required=False,
737
+ **args):
738
+ """Registers a flag whose value can be any string from enum_values.
739
+
740
+ Instead of a string enum, prefer `DEFINE_enum_class`, which allows
741
+ defining enums from an `enum.Enum` class.
742
+
743
+ Args:
744
+ name: str, the flag name.
745
+ default: str|None, the default value of the flag.
746
+ enum_values: [str], a non-empty list of strings with the possible values for
747
+ the flag.
748
+ help: str, the help message.
749
+ flag_values: :class:`FlagValues`, the FlagValues instance with which the
750
+ flag will be registered. This should almost never need to be overridden.
751
+ module_name: str, the name of the Python module declaring this flag. If not
752
+ provided, it will be computed using the stack trace of this call.
753
+ required: bool, is this a required flag. This must be used as a keyword
754
+ argument.
755
+ **args: dict, the extra keyword args that are passed to ``Flag.__init__``.
756
+
757
+ Returns:
758
+ a handle to defined flag.
759
+ """
760
+ result = DEFINE_flag(
761
+ _flag.EnumFlag(name, default, help, enum_values, **args),
762
+ flag_values,
763
+ module_name,
764
+ required=True if required else False,
765
+ )
766
+ return result
767
+
768
+
769
+ @overload
770
+ def DEFINE_enum_class( # pylint: disable=invalid-name
771
+ name: Text,
772
+ default: Union[None, _ET, Text],
773
+ enum_class: Type[_ET],
774
+ help: Optional[Text], # pylint: disable=redefined-builtin
775
+ flag_values: _flagvalues.FlagValues = ...,
776
+ module_name: Optional[Text] = ...,
777
+ case_sensitive: bool = ...,
778
+ *,
779
+ required: 'typing.Literal[True]',
780
+ **args: Any
781
+ ) -> _flagvalues.FlagHolder[_ET]:
782
+ ...
783
+
784
+
785
+ @overload
786
+ def DEFINE_enum_class( # pylint: disable=invalid-name
787
+ name: Text,
788
+ default: None,
789
+ enum_class: Type[_ET],
790
+ help: Optional[Text], # pylint: disable=redefined-builtin
791
+ flag_values: _flagvalues.FlagValues = ...,
792
+ module_name: Optional[Text] = ...,
793
+ case_sensitive: bool = ...,
794
+ required: bool = ...,
795
+ **args: Any
796
+ ) -> _flagvalues.FlagHolder[Optional[_ET]]:
797
+ ...
798
+
799
+
800
+ @overload
801
+ def DEFINE_enum_class( # pylint: disable=invalid-name
802
+ name: Text,
803
+ default: Union[_ET, Text],
804
+ enum_class: Type[_ET],
805
+ help: Optional[Text], # pylint: disable=redefined-builtin
806
+ flag_values: _flagvalues.FlagValues = ...,
807
+ module_name: Optional[Text] = ...,
808
+ case_sensitive: bool = ...,
809
+ required: bool = ...,
810
+ **args: Any
811
+ ) -> _flagvalues.FlagHolder[_ET]:
812
+ ...
813
+
814
+
815
+ def DEFINE_enum_class( # pylint: disable=invalid-name,redefined-builtin
816
+ name,
817
+ default,
818
+ enum_class,
819
+ help,
820
+ flag_values=_flagvalues.FLAGS,
821
+ module_name=None,
822
+ case_sensitive=False,
823
+ required=False,
824
+ **args):
825
+ """Registers a flag whose value can be the name of enum members.
826
+
827
+ Args:
828
+ name: str, the flag name.
829
+ default: Enum|str|None, the default value of the flag.
830
+ enum_class: class, the Enum class with all the possible values for the flag.
831
+ help: str, the help message.
832
+ flag_values: :class:`FlagValues`, the FlagValues instance with which the
833
+ flag will be registered. This should almost never need to be overridden.
834
+ module_name: str, the name of the Python module declaring this flag. If not
835
+ provided, it will be computed using the stack trace of this call.
836
+ case_sensitive: bool, whether to map strings to members of the enum_class
837
+ without considering case.
838
+ required: bool, is this a required flag. This must be used as a keyword
839
+ argument.
840
+ **args: dict, the extra keyword args that are passed to ``Flag.__init__``.
841
+
842
+ Returns:
843
+ a handle to defined flag.
844
+ """
845
+ # NOTE: pytype fails if this is a direct return.
846
+ result = DEFINE_flag(
847
+ _flag.EnumClassFlag(
848
+ name, default, help, enum_class, case_sensitive=case_sensitive, **args
849
+ ),
850
+ flag_values,
851
+ module_name,
852
+ required=True if required else False,
853
+ )
854
+ return result
855
+
856
+
857
+ @overload
858
+ def DEFINE_list( # pylint: disable=invalid-name
859
+ name: Text,
860
+ default: Union[None, Iterable[Text], Text],
861
+ help: Text, # pylint: disable=redefined-builtin
862
+ flag_values: _flagvalues.FlagValues = ...,
863
+ *,
864
+ required: 'typing.Literal[True]',
865
+ **args: Any
866
+ ) -> _flagvalues.FlagHolder[List[Text]]:
867
+ ...
868
+
869
+
870
+ @overload
871
+ def DEFINE_list( # pylint: disable=invalid-name
872
+ name: Text,
873
+ default: None,
874
+ help: Text, # pylint: disable=redefined-builtin
875
+ flag_values: _flagvalues.FlagValues = ...,
876
+ required: bool = ...,
877
+ **args: Any
878
+ ) -> _flagvalues.FlagHolder[Optional[List[Text]]]:
879
+ ...
880
+
881
+
882
+ @overload
883
+ def DEFINE_list( # pylint: disable=invalid-name
884
+ name: Text,
885
+ default: Union[Iterable[Text], Text],
886
+ help: Text, # pylint: disable=redefined-builtin
887
+ flag_values: _flagvalues.FlagValues = ...,
888
+ required: bool = ...,
889
+ **args: Any
890
+ ) -> _flagvalues.FlagHolder[List[Text]]:
891
+ ...
892
+
893
+
894
+ def DEFINE_list( # pylint: disable=invalid-name,redefined-builtin
895
+ name,
896
+ default,
897
+ help,
898
+ flag_values=_flagvalues.FLAGS,
899
+ required=False,
900
+ **args):
901
+ """Registers a flag whose value is a comma-separated list of strings.
902
+
903
+ The flag value is parsed with a CSV parser.
904
+
905
+ Args:
906
+ name: str, the flag name.
907
+ default: list|str|None, the default value of the flag.
908
+ help: str, the help message.
909
+ flag_values: :class:`FlagValues`, the FlagValues instance with which the
910
+ flag will be registered. This should almost never need to be overridden.
911
+ required: bool, is this a required flag. This must be used as a keyword
912
+ argument.
913
+ **args: Dictionary with extra keyword args that are passed to the
914
+ ``Flag.__init__``.
915
+
916
+ Returns:
917
+ a handle to defined flag.
918
+ """
919
+ parser = _argument_parser.ListParser()
920
+ serializer = _argument_parser.CsvListSerializer(',')
921
+ return DEFINE(
922
+ parser,
923
+ name,
924
+ default,
925
+ help,
926
+ flag_values,
927
+ serializer,
928
+ required=True if required else False,
929
+ **args,
930
+ )
931
+
932
+
933
+ @overload
934
+ def DEFINE_spaceseplist( # pylint: disable=invalid-name
935
+ name: Text,
936
+ default: Union[None, Iterable[Text], Text],
937
+ help: Text, # pylint: disable=redefined-builtin
938
+ comma_compat: bool = ...,
939
+ flag_values: _flagvalues.FlagValues = ...,
940
+ *,
941
+ required: 'typing.Literal[True]',
942
+ **args: Any
943
+ ) -> _flagvalues.FlagHolder[List[Text]]:
944
+ ...
945
+
946
+
947
+ @overload
948
+ def DEFINE_spaceseplist( # pylint: disable=invalid-name
949
+ name: Text,
950
+ default: None,
951
+ help: Text, # pylint: disable=redefined-builtin
952
+ comma_compat: bool = ...,
953
+ flag_values: _flagvalues.FlagValues = ...,
954
+ required: bool = ...,
955
+ **args: Any
956
+ ) -> _flagvalues.FlagHolder[Optional[List[Text]]]:
957
+ ...
958
+
959
+
960
+ @overload
961
+ def DEFINE_spaceseplist( # pylint: disable=invalid-name
962
+ name: Text,
963
+ default: Union[Iterable[Text], Text],
964
+ help: Text, # pylint: disable=redefined-builtin
965
+ comma_compat: bool = ...,
966
+ flag_values: _flagvalues.FlagValues = ...,
967
+ required: bool = ...,
968
+ **args: Any
969
+ ) -> _flagvalues.FlagHolder[List[Text]]:
970
+ ...
971
+
972
+
973
+ def DEFINE_spaceseplist( # pylint: disable=invalid-name,redefined-builtin
974
+ name,
975
+ default,
976
+ help,
977
+ comma_compat=False,
978
+ flag_values=_flagvalues.FLAGS,
979
+ required=False,
980
+ **args):
981
+ """Registers a flag whose value is a whitespace-separated list of strings.
982
+
983
+ Any whitespace can be used as a separator.
984
+
985
+ Args:
986
+ name: str, the flag name.
987
+ default: list|str|None, the default value of the flag.
988
+ help: str, the help message.
989
+ comma_compat: bool - Whether to support comma as an additional separator. If
990
+ false then only whitespace is supported. This is intended only for
991
+ backwards compatibility with flags that used to be comma-separated.
992
+ flag_values: :class:`FlagValues`, the FlagValues instance with which the
993
+ flag will be registered. This should almost never need to be overridden.
994
+ required: bool, is this a required flag. This must be used as a keyword
995
+ argument.
996
+ **args: Dictionary with extra keyword args that are passed to the
997
+ ``Flag.__init__``.
998
+
999
+ Returns:
1000
+ a handle to defined flag.
1001
+ """
1002
+ parser = _argument_parser.WhitespaceSeparatedListParser(
1003
+ comma_compat=comma_compat)
1004
+ serializer = _argument_parser.ListSerializer(' ')
1005
+ return DEFINE(
1006
+ parser,
1007
+ name,
1008
+ default,
1009
+ help,
1010
+ flag_values,
1011
+ serializer,
1012
+ required=True if required else False,
1013
+ **args,
1014
+ )
1015
+
1016
+
1017
+ @overload
1018
+ def DEFINE_multi( # pylint: disable=invalid-name
1019
+ parser: _argument_parser.ArgumentParser[_T],
1020
+ serializer: _argument_parser.ArgumentSerializer[_T],
1021
+ name: Text,
1022
+ default: Iterable[_T],
1023
+ help: Text, # pylint: disable=redefined-builtin
1024
+ flag_values: _flagvalues.FlagValues = ...,
1025
+ module_name: Optional[Text] = ...,
1026
+ *,
1027
+ required: 'typing.Literal[True]',
1028
+ **args: Any
1029
+ ) -> _flagvalues.FlagHolder[List[_T]]:
1030
+ ...
1031
+
1032
+
1033
+ @overload
1034
+ def DEFINE_multi( # pylint: disable=invalid-name
1035
+ parser: _argument_parser.ArgumentParser[_T],
1036
+ serializer: _argument_parser.ArgumentSerializer[_T],
1037
+ name: Text,
1038
+ default: Union[None, _T],
1039
+ help: Text, # pylint: disable=redefined-builtin
1040
+ flag_values: _flagvalues.FlagValues = ...,
1041
+ module_name: Optional[Text] = ...,
1042
+ *,
1043
+ required: 'typing.Literal[True]',
1044
+ **args: Any
1045
+ ) -> _flagvalues.FlagHolder[List[_T]]:
1046
+ ...
1047
+
1048
+
1049
+ @overload
1050
+ def DEFINE_multi( # pylint: disable=invalid-name
1051
+ parser: _argument_parser.ArgumentParser[_T],
1052
+ serializer: _argument_parser.ArgumentSerializer[_T],
1053
+ name: Text,
1054
+ default: None,
1055
+ help: Text, # pylint: disable=redefined-builtin
1056
+ flag_values: _flagvalues.FlagValues = ...,
1057
+ module_name: Optional[Text] = ...,
1058
+ required: bool = ...,
1059
+ **args: Any
1060
+ ) -> _flagvalues.FlagHolder[Optional[List[_T]]]:
1061
+ ...
1062
+
1063
+
1064
+ @overload
1065
+ def DEFINE_multi( # pylint: disable=invalid-name
1066
+ parser: _argument_parser.ArgumentParser[_T],
1067
+ serializer: _argument_parser.ArgumentSerializer[_T],
1068
+ name: Text,
1069
+ default: Iterable[_T],
1070
+ help: Text, # pylint: disable=redefined-builtin
1071
+ flag_values: _flagvalues.FlagValues = ...,
1072
+ module_name: Optional[Text] = ...,
1073
+ required: bool = ...,
1074
+ **args: Any
1075
+ ) -> _flagvalues.FlagHolder[List[_T]]:
1076
+ ...
1077
+
1078
+
1079
+ @overload
1080
+ def DEFINE_multi( # pylint: disable=invalid-name
1081
+ parser: _argument_parser.ArgumentParser[_T],
1082
+ serializer: _argument_parser.ArgumentSerializer[_T],
1083
+ name: Text,
1084
+ default: _T,
1085
+ help: Text, # pylint: disable=redefined-builtin
1086
+ flag_values: _flagvalues.FlagValues = ...,
1087
+ module_name: Optional[Text] = ...,
1088
+ required: bool = ...,
1089
+ **args: Any
1090
+ ) -> _flagvalues.FlagHolder[List[_T]]:
1091
+ ...
1092
+
1093
+
1094
+ def DEFINE_multi( # pylint: disable=invalid-name,redefined-builtin
1095
+ parser,
1096
+ serializer,
1097
+ name,
1098
+ default,
1099
+ help,
1100
+ flag_values=_flagvalues.FLAGS,
1101
+ module_name=None,
1102
+ required=False,
1103
+ **args):
1104
+ """Registers a generic MultiFlag that parses its args with a given parser.
1105
+
1106
+ Auxiliary function. Normal users should NOT use it directly.
1107
+
1108
+ Developers who need to create their own 'Parser' classes for options
1109
+ which can appear multiple times can call this module function to
1110
+ register their flags.
1111
+
1112
+ Args:
1113
+ parser: ArgumentParser, used to parse the flag arguments.
1114
+ serializer: ArgumentSerializer, the flag serializer instance.
1115
+ name: str, the flag name.
1116
+ default: Union[Iterable[T], Text, None], the default value of the flag. If
1117
+ the value is text, it will be parsed as if it was provided from the
1118
+ command line. If the value is a non-string iterable, it will be iterated
1119
+ over to create a shallow copy of the values. If it is None, it is left
1120
+ as-is.
1121
+ help: str, the help message.
1122
+ flag_values: :class:`FlagValues`, the FlagValues instance with which the
1123
+ flag will be registered. This should almost never need to be overridden.
1124
+ module_name: A string, the name of the Python module declaring this flag. If
1125
+ not provided, it will be computed using the stack trace of this call.
1126
+ required: bool, is this a required flag. This must be used as a keyword
1127
+ argument.
1128
+ **args: Dictionary with extra keyword args that are passed to the
1129
+ ``Flag.__init__``.
1130
+
1131
+ Returns:
1132
+ a handle to defined flag.
1133
+ """
1134
+ result = DEFINE_flag(
1135
+ _flag.MultiFlag(parser, serializer, name, default, help, **args),
1136
+ flag_values,
1137
+ module_name,
1138
+ required=True if required else False,
1139
+ )
1140
+ return result
1141
+
1142
+
1143
+ @overload
1144
+ def DEFINE_multi_string( # pylint: disable=invalid-name
1145
+ name: Text,
1146
+ default: Union[None, Iterable[Text], Text],
1147
+ help: Text, # pylint: disable=redefined-builtin
1148
+ flag_values: _flagvalues.FlagValues = ...,
1149
+ *,
1150
+ required: 'typing.Literal[True]',
1151
+ **args: Any
1152
+ ) -> _flagvalues.FlagHolder[List[Text]]:
1153
+ ...
1154
+
1155
+
1156
+ @overload
1157
+ def DEFINE_multi_string( # pylint: disable=invalid-name
1158
+ name: Text,
1159
+ default: None,
1160
+ help: Text, # pylint: disable=redefined-builtin
1161
+ flag_values: _flagvalues.FlagValues = ...,
1162
+ required: bool = ...,
1163
+ **args: Any
1164
+ ) -> _flagvalues.FlagHolder[Optional[List[Text]]]:
1165
+ ...
1166
+
1167
+
1168
+ @overload
1169
+ def DEFINE_multi_string( # pylint: disable=invalid-name
1170
+ name: Text,
1171
+ default: Union[Iterable[Text], Text],
1172
+ help: Text, # pylint: disable=redefined-builtin
1173
+ flag_values: _flagvalues.FlagValues = ...,
1174
+ required: bool = ...,
1175
+ **args: Any
1176
+ ) -> _flagvalues.FlagHolder[List[Text]]:
1177
+ ...
1178
+
1179
+
1180
+ def DEFINE_multi_string( # pylint: disable=invalid-name,redefined-builtin
1181
+ name,
1182
+ default,
1183
+ help,
1184
+ flag_values=_flagvalues.FLAGS,
1185
+ required=False,
1186
+ **args):
1187
+ """Registers a flag whose value can be a list of any strings.
1188
+
1189
+ Use the flag on the command line multiple times to place multiple
1190
+ string values into the list. The 'default' may be a single string
1191
+ (which will be converted into a single-element list) or a list of
1192
+ strings.
1193
+
1194
+
1195
+ Args:
1196
+ name: str, the flag name.
1197
+ default: Union[Iterable[Text], Text, None], the default value of the flag;
1198
+ see :func:`DEFINE_multi`.
1199
+ help: str, the help message.
1200
+ flag_values: :class:`FlagValues`, the FlagValues instance with which the
1201
+ flag will be registered. This should almost never need to be overridden.
1202
+ required: bool, is this a required flag. This must be used as a keyword
1203
+ argument.
1204
+ **args: Dictionary with extra keyword args that are passed to the
1205
+ ``Flag.__init__``.
1206
+
1207
+ Returns:
1208
+ a handle to defined flag.
1209
+ """
1210
+ parser = _argument_parser.ArgumentParser()
1211
+ serializer = _argument_parser.ArgumentSerializer()
1212
+ return DEFINE_multi(
1213
+ parser,
1214
+ serializer,
1215
+ name,
1216
+ default,
1217
+ help,
1218
+ flag_values,
1219
+ required=True if required else False,
1220
+ **args,
1221
+ )
1222
+
1223
+
1224
+ @overload
1225
+ def DEFINE_multi_integer( # pylint: disable=invalid-name
1226
+ name: Text,
1227
+ default: Union[None, Iterable[int], int, Text],
1228
+ help: Text, # pylint: disable=redefined-builtin
1229
+ lower_bound: Optional[int] = ...,
1230
+ upper_bound: Optional[int] = ...,
1231
+ flag_values: _flagvalues.FlagValues = ...,
1232
+ *,
1233
+ required: 'typing.Literal[True]',
1234
+ **args: Any
1235
+ ) -> _flagvalues.FlagHolder[List[int]]:
1236
+ ...
1237
+
1238
+
1239
+ @overload
1240
+ def DEFINE_multi_integer( # pylint: disable=invalid-name
1241
+ name: Text,
1242
+ default: None,
1243
+ help: Text, # pylint: disable=redefined-builtin
1244
+ lower_bound: Optional[int] = ...,
1245
+ upper_bound: Optional[int] = ...,
1246
+ flag_values: _flagvalues.FlagValues = ...,
1247
+ required: bool = ...,
1248
+ **args: Any
1249
+ ) -> _flagvalues.FlagHolder[Optional[List[int]]]:
1250
+ ...
1251
+
1252
+
1253
+ @overload
1254
+ def DEFINE_multi_integer( # pylint: disable=invalid-name
1255
+ name: Text,
1256
+ default: Union[Iterable[int], int, Text],
1257
+ help: Text, # pylint: disable=redefined-builtin
1258
+ lower_bound: Optional[int] = ...,
1259
+ upper_bound: Optional[int] = ...,
1260
+ flag_values: _flagvalues.FlagValues = ...,
1261
+ required: bool = ...,
1262
+ **args: Any
1263
+ ) -> _flagvalues.FlagHolder[List[int]]:
1264
+ ...
1265
+
1266
+
1267
+ def DEFINE_multi_integer( # pylint: disable=invalid-name,redefined-builtin
1268
+ name,
1269
+ default,
1270
+ help,
1271
+ lower_bound=None,
1272
+ upper_bound=None,
1273
+ flag_values=_flagvalues.FLAGS,
1274
+ required=False,
1275
+ **args):
1276
+ """Registers a flag whose value can be a list of arbitrary integers.
1277
+
1278
+ Use the flag on the command line multiple times to place multiple
1279
+ integer values into the list. The 'default' may be a single integer
1280
+ (which will be converted into a single-element list) or a list of
1281
+ integers.
1282
+
1283
+ Args:
1284
+ name: str, the flag name.
1285
+ default: Union[Iterable[int], Text, None], the default value of the flag;
1286
+ see `DEFINE_multi`.
1287
+ help: str, the help message.
1288
+ lower_bound: int, min values of the flag.
1289
+ upper_bound: int, max values of the flag.
1290
+ flag_values: :class:`FlagValues`, the FlagValues instance with which the
1291
+ flag will be registered. This should almost never need to be overridden.
1292
+ required: bool, is this a required flag. This must be used as a keyword
1293
+ argument.
1294
+ **args: Dictionary with extra keyword args that are passed to the
1295
+ ``Flag.__init__``.
1296
+
1297
+ Returns:
1298
+ a handle to defined flag.
1299
+ """
1300
+ parser = _argument_parser.IntegerParser(lower_bound, upper_bound)
1301
+ serializer = _argument_parser.ArgumentSerializer()
1302
+ return DEFINE_multi(
1303
+ parser,
1304
+ serializer,
1305
+ name,
1306
+ default,
1307
+ help,
1308
+ flag_values,
1309
+ required=True if required else False,
1310
+ **args,
1311
+ )
1312
+
1313
+
1314
+ @overload
1315
+ def DEFINE_multi_float( # pylint: disable=invalid-name
1316
+ name: Text,
1317
+ default: Union[None, Iterable[float], float, Text],
1318
+ help: Text, # pylint: disable=redefined-builtin
1319
+ lower_bound: Optional[float] = ...,
1320
+ upper_bound: Optional[float] = ...,
1321
+ flag_values: _flagvalues.FlagValues = ...,
1322
+ *,
1323
+ required: 'typing.Literal[True]',
1324
+ **args: Any
1325
+ ) -> _flagvalues.FlagHolder[List[float]]:
1326
+ ...
1327
+
1328
+
1329
+ @overload
1330
+ def DEFINE_multi_float( # pylint: disable=invalid-name
1331
+ name: Text,
1332
+ default: None,
1333
+ help: Text, # pylint: disable=redefined-builtin
1334
+ lower_bound: Optional[float] = ...,
1335
+ upper_bound: Optional[float] = ...,
1336
+ flag_values: _flagvalues.FlagValues = ...,
1337
+ required: bool = ...,
1338
+ **args: Any
1339
+ ) -> _flagvalues.FlagHolder[Optional[List[float]]]:
1340
+ ...
1341
+
1342
+
1343
+ @overload
1344
+ def DEFINE_multi_float( # pylint: disable=invalid-name
1345
+ name: Text,
1346
+ default: Union[Iterable[float], float, Text],
1347
+ help: Text, # pylint: disable=redefined-builtin
1348
+ lower_bound: Optional[float] = ...,
1349
+ upper_bound: Optional[float] = ...,
1350
+ flag_values: _flagvalues.FlagValues = ...,
1351
+ required: bool = ...,
1352
+ **args: Any
1353
+ ) -> _flagvalues.FlagHolder[List[float]]:
1354
+ ...
1355
+
1356
+
1357
+ def DEFINE_multi_float( # pylint: disable=invalid-name,redefined-builtin
1358
+ name,
1359
+ default,
1360
+ help,
1361
+ lower_bound=None,
1362
+ upper_bound=None,
1363
+ flag_values=_flagvalues.FLAGS,
1364
+ required=False,
1365
+ **args):
1366
+ """Registers a flag whose value can be a list of arbitrary floats.
1367
+
1368
+ Use the flag on the command line multiple times to place multiple
1369
+ float values into the list. The 'default' may be a single float
1370
+ (which will be converted into a single-element list) or a list of
1371
+ floats.
1372
+
1373
+ Args:
1374
+ name: str, the flag name.
1375
+ default: Union[Iterable[float], Text, None], the default value of the flag;
1376
+ see `DEFINE_multi`.
1377
+ help: str, the help message.
1378
+ lower_bound: float, min values of the flag.
1379
+ upper_bound: float, max values of the flag.
1380
+ flag_values: :class:`FlagValues`, the FlagValues instance with which the
1381
+ flag will be registered. This should almost never need to be overridden.
1382
+ required: bool, is this a required flag. This must be used as a keyword
1383
+ argument.
1384
+ **args: Dictionary with extra keyword args that are passed to the
1385
+ ``Flag.__init__``.
1386
+
1387
+ Returns:
1388
+ a handle to defined flag.
1389
+ """
1390
+ parser = _argument_parser.FloatParser(lower_bound, upper_bound)
1391
+ serializer = _argument_parser.ArgumentSerializer()
1392
+ return DEFINE_multi(
1393
+ parser,
1394
+ serializer,
1395
+ name,
1396
+ default,
1397
+ help,
1398
+ flag_values,
1399
+ required=True if required else False,
1400
+ **args,
1401
+ )
1402
+
1403
+
1404
+ @overload
1405
+ def DEFINE_multi_enum( # pylint: disable=invalid-name
1406
+ name: Text,
1407
+ default: Union[None, Iterable[Text], Text],
1408
+ enum_values: Iterable[Text],
1409
+ help: Text, # pylint: disable=redefined-builtin
1410
+ flag_values: _flagvalues.FlagValues = ...,
1411
+ *,
1412
+ required: 'typing.Literal[True]',
1413
+ **args: Any
1414
+ ) -> _flagvalues.FlagHolder[List[Text]]:
1415
+ ...
1416
+
1417
+
1418
+ @overload
1419
+ def DEFINE_multi_enum( # pylint: disable=invalid-name
1420
+ name: Text,
1421
+ default: None,
1422
+ enum_values: Iterable[Text],
1423
+ help: Text, # pylint: disable=redefined-builtin
1424
+ flag_values: _flagvalues.FlagValues = ...,
1425
+ required: bool = ...,
1426
+ **args: Any
1427
+ ) -> _flagvalues.FlagHolder[Optional[List[Text]]]:
1428
+ ...
1429
+
1430
+
1431
+ @overload
1432
+ def DEFINE_multi_enum( # pylint: disable=invalid-name
1433
+ name: Text,
1434
+ default: Union[Iterable[Text], Text],
1435
+ enum_values: Iterable[Text],
1436
+ help: Text, # pylint: disable=redefined-builtin
1437
+ flag_values: _flagvalues.FlagValues = ...,
1438
+ required: bool = ...,
1439
+ **args: Any
1440
+ ) -> _flagvalues.FlagHolder[List[Text]]:
1441
+ ...
1442
+
1443
+
1444
+ def DEFINE_multi_enum( # pylint: disable=invalid-name,redefined-builtin
1445
+ name,
1446
+ default,
1447
+ enum_values,
1448
+ help,
1449
+ flag_values=_flagvalues.FLAGS,
1450
+ case_sensitive=True,
1451
+ required=False,
1452
+ **args):
1453
+ """Registers a flag whose value can be a list strings from enum_values.
1454
+
1455
+ Use the flag on the command line multiple times to place multiple
1456
+ enum values into the list. The 'default' may be a single string
1457
+ (which will be converted into a single-element list) or a list of
1458
+ strings.
1459
+
1460
+ Args:
1461
+ name: str, the flag name.
1462
+ default: Union[Iterable[Text], Text, None], the default value of the flag;
1463
+ see `DEFINE_multi`.
1464
+ enum_values: [str], a non-empty list of strings with the possible values for
1465
+ the flag.
1466
+ help: str, the help message.
1467
+ flag_values: :class:`FlagValues`, the FlagValues instance with which the
1468
+ flag will be registered. This should almost never need to be overridden.
1469
+ case_sensitive: Whether or not the enum is to be case-sensitive.
1470
+ required: bool, is this a required flag. This must be used as a keyword
1471
+ argument.
1472
+ **args: Dictionary with extra keyword args that are passed to the
1473
+ ``Flag.__init__``.
1474
+
1475
+ Returns:
1476
+ a handle to defined flag.
1477
+ """
1478
+ parser = _argument_parser.EnumParser(enum_values, case_sensitive)
1479
+ serializer = _argument_parser.ArgumentSerializer()
1480
+ return DEFINE_multi(
1481
+ parser,
1482
+ serializer,
1483
+ name,
1484
+ default,
1485
+ '<%s>: %s' % ('|'.join(enum_values), help),
1486
+ flag_values,
1487
+ required=True if required else False,
1488
+ **args,
1489
+ )
1490
+
1491
+
1492
+ @overload
1493
+ def DEFINE_multi_enum_class( # pylint: disable=invalid-name
1494
+ name: Text,
1495
+ # This is separate from `Union[None, _ET, Iterable[Text], Text]` to avoid a
1496
+ # Pytype issue inferring the return value to
1497
+ # FlagHolder[List[Union[_ET, enum.Enum]]] when an iterable of concrete enum
1498
+ # subclasses are used.
1499
+ default: Iterable[_ET],
1500
+ enum_class: Type[_ET],
1501
+ help: Text, # pylint: disable=redefined-builtin
1502
+ flag_values: _flagvalues.FlagValues = ...,
1503
+ module_name: Optional[Text] = ...,
1504
+ *,
1505
+ required: 'typing.Literal[True]',
1506
+ **args: Any
1507
+ ) -> _flagvalues.FlagHolder[List[_ET]]:
1508
+ ...
1509
+
1510
+
1511
+ @overload
1512
+ def DEFINE_multi_enum_class( # pylint: disable=invalid-name
1513
+ name: Text,
1514
+ default: Union[None, _ET, Iterable[Text], Text],
1515
+ enum_class: Type[_ET],
1516
+ help: Text, # pylint: disable=redefined-builtin
1517
+ flag_values: _flagvalues.FlagValues = ...,
1518
+ module_name: Optional[Text] = ...,
1519
+ *,
1520
+ required: 'typing.Literal[True]',
1521
+ **args: Any
1522
+ ) -> _flagvalues.FlagHolder[List[_ET]]:
1523
+ ...
1524
+
1525
+
1526
+ @overload
1527
+ def DEFINE_multi_enum_class( # pylint: disable=invalid-name
1528
+ name: Text,
1529
+ default: None,
1530
+ enum_class: Type[_ET],
1531
+ help: Text, # pylint: disable=redefined-builtin
1532
+ flag_values: _flagvalues.FlagValues = ...,
1533
+ module_name: Optional[Text] = ...,
1534
+ required: bool = ...,
1535
+ **args: Any
1536
+ ) -> _flagvalues.FlagHolder[Optional[List[_ET]]]:
1537
+ ...
1538
+
1539
+
1540
+ @overload
1541
+ def DEFINE_multi_enum_class( # pylint: disable=invalid-name
1542
+ name: Text,
1543
+ # This is separate from `Union[None, _ET, Iterable[Text], Text]` to avoid a
1544
+ # Pytype issue inferring the return value to
1545
+ # FlagHolder[List[Union[_ET, enum.Enum]]] when an iterable of concrete enum
1546
+ # subclasses are used.
1547
+ default: Iterable[_ET],
1548
+ enum_class: Type[_ET],
1549
+ help: Text, # pylint: disable=redefined-builtin
1550
+ flag_values: _flagvalues.FlagValues = ...,
1551
+ module_name: Optional[Text] = ...,
1552
+ required: bool = ...,
1553
+ **args: Any
1554
+ ) -> _flagvalues.FlagHolder[List[_ET]]:
1555
+ ...
1556
+
1557
+
1558
+ @overload
1559
+ def DEFINE_multi_enum_class( # pylint: disable=invalid-name
1560
+ name: Text,
1561
+ default: Union[_ET, Iterable[Text], Text],
1562
+ enum_class: Type[_ET],
1563
+ help: Text, # pylint: disable=redefined-builtin
1564
+ flag_values: _flagvalues.FlagValues = ...,
1565
+ module_name: Optional[Text] = ...,
1566
+ required: bool = ...,
1567
+ **args: Any
1568
+ ) -> _flagvalues.FlagHolder[List[_ET]]:
1569
+ ...
1570
+
1571
+
1572
+ def DEFINE_multi_enum_class( # pylint: disable=invalid-name,redefined-builtin
1573
+ name,
1574
+ default,
1575
+ enum_class,
1576
+ help,
1577
+ flag_values=_flagvalues.FLAGS,
1578
+ module_name=None,
1579
+ case_sensitive=False,
1580
+ required=False,
1581
+ **args):
1582
+ """Registers a flag whose value can be a list of enum members.
1583
+
1584
+ Use the flag on the command line multiple times to place multiple
1585
+ enum values into the list.
1586
+
1587
+ Args:
1588
+ name: str, the flag name.
1589
+ default: Union[Iterable[Enum], Iterable[Text], Enum, Text, None], the
1590
+ default value of the flag; see `DEFINE_multi`; only differences are
1591
+ documented here. If the value is a single Enum, it is treated as a
1592
+ single-item list of that Enum value. If it is an iterable, text values
1593
+ within the iterable will be converted to the equivalent Enum objects.
1594
+ enum_class: class, the Enum class with all the possible values for the flag.
1595
+ help: str, the help message.
1596
+ flag_values: :class:`FlagValues`, the FlagValues instance with which the
1597
+ flag will be registered. This should almost never need to be overridden.
1598
+ module_name: A string, the name of the Python module declaring this flag. If
1599
+ not provided, it will be computed using the stack trace of this call.
1600
+ case_sensitive: bool, whether to map strings to members of the enum_class
1601
+ without considering case.
1602
+ required: bool, is this a required flag. This must be used as a keyword
1603
+ argument.
1604
+ **args: Dictionary with extra keyword args that are passed to the
1605
+ ``Flag.__init__``.
1606
+
1607
+ Returns:
1608
+ a handle to defined flag.
1609
+ """
1610
+ # NOTE: pytype fails if this is a direct return.
1611
+ result = DEFINE_flag(
1612
+ _flag.MultiEnumClassFlag(
1613
+ name,
1614
+ default,
1615
+ help,
1616
+ enum_class,
1617
+ case_sensitive=case_sensitive,
1618
+ **args,
1619
+ ),
1620
+ flag_values,
1621
+ module_name,
1622
+ required=True if required else False,
1623
+ )
1624
+ return result
1625
+
1626
+
1627
+ def DEFINE_alias( # pylint: disable=invalid-name
1628
+ name: Text,
1629
+ original_name: Text,
1630
+ flag_values: _flagvalues.FlagValues = _flagvalues.FLAGS,
1631
+ module_name: Optional[Text] = None,
1632
+ ) -> _flagvalues.FlagHolder[Any]:
1633
+ """Defines an alias flag for an existing one.
1634
+
1635
+ Args:
1636
+ name: str, the flag name.
1637
+ original_name: str, the original flag name.
1638
+ flag_values: :class:`FlagValues`, the FlagValues instance with which the
1639
+ flag will be registered. This should almost never need to be overridden.
1640
+ module_name: A string, the name of the module that defines this flag.
1641
+
1642
+ Returns:
1643
+ a handle to defined flag.
1644
+
1645
+ Raises:
1646
+ flags.FlagError:
1647
+ UnrecognizedFlagError: if the referenced flag doesn't exist.
1648
+ DuplicateFlagError: if the alias name has been used by some existing flag.
1649
+ """
1650
+ if original_name not in flag_values:
1651
+ raise _exceptions.UnrecognizedFlagError(original_name)
1652
+ flag = flag_values[original_name]
1653
+
1654
+ class _FlagAlias(_flag.Flag):
1655
+ """Overrides Flag class so alias value is copy of original flag value."""
1656
+
1657
+ def parse(self, argument):
1658
+ flag.parse(argument)
1659
+ self.present += 1
1660
+
1661
+ def _parse_from_default(self, value):
1662
+ # The value was already parsed by the aliased flag, so there is no
1663
+ # need to call the parser on it a second time.
1664
+ # Additionally, because of how MultiFlag parses and merges values,
1665
+ # it isn't possible to delegate to the aliased flag and still get
1666
+ # the correct values.
1667
+ return value
1668
+
1669
+ @property
1670
+ def value(self):
1671
+ return flag.value
1672
+
1673
+ @value.setter
1674
+ def value(self, value):
1675
+ flag.value = value
1676
+
1677
+ help_msg = 'Alias for --%s.' % flag.name
1678
+ # If alias_name has been used, flags.DuplicatedFlag will be raised.
1679
+ return DEFINE_flag(
1680
+ _FlagAlias(
1681
+ flag.parser,
1682
+ flag.serializer,
1683
+ name,
1684
+ flag.default,
1685
+ help_msg,
1686
+ boolean=flag.boolean), flag_values, module_name)
MLPY/Lib/site-packages/absl/flags/_exceptions.py ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2017 The Abseil Authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Exception classes in ABSL flags library.
16
+
17
+ Do NOT import this module directly. Import the flags package and use the
18
+ aliases defined at the package level instead.
19
+ """
20
+
21
+ import sys
22
+
23
+ from absl.flags import _helpers
24
+
25
+
26
+ _helpers.disclaim_module_ids.add(id(sys.modules[__name__]))
27
+
28
+
29
+ class Error(Exception):
30
+ """The base class for all flags errors."""
31
+
32
+
33
+ class CantOpenFlagFileError(Error):
34
+ """Raised when flagfile fails to open.
35
+
36
+ E.g. the file doesn't exist, or has wrong permissions.
37
+ """
38
+
39
+
40
+ class DuplicateFlagError(Error):
41
+ """Raised if there is a flag naming conflict."""
42
+
43
+ @classmethod
44
+ def from_flag(cls, flagname, flag_values, other_flag_values=None):
45
+ """Creates a DuplicateFlagError by providing flag name and values.
46
+
47
+ Args:
48
+ flagname: str, the name of the flag being redefined.
49
+ flag_values: :class:`FlagValues`, the FlagValues instance containing the
50
+ first definition of flagname.
51
+ other_flag_values: :class:`FlagValues`, if it is not None, it should be
52
+ the FlagValues object where the second definition of flagname occurs.
53
+ If it is None, we assume that we're being called when attempting to
54
+ create the flag a second time, and we use the module calling this one
55
+ as the source of the second definition.
56
+
57
+ Returns:
58
+ An instance of DuplicateFlagError.
59
+ """
60
+ first_module = flag_values.find_module_defining_flag(
61
+ flagname, default='<unknown>')
62
+ if other_flag_values is None:
63
+ second_module = _helpers.get_calling_module()
64
+ else:
65
+ second_module = other_flag_values.find_module_defining_flag(
66
+ flagname, default='<unknown>')
67
+ flag_summary = flag_values[flagname].help
68
+ msg = ("The flag '%s' is defined twice. First from %s, Second from %s. "
69
+ "Description from first occurrence: %s") % (
70
+ flagname, first_module, second_module, flag_summary)
71
+ return cls(msg)
72
+
73
+
74
+ class IllegalFlagValueError(Error):
75
+ """Raised when the flag command line argument is illegal."""
76
+
77
+
78
+ class UnrecognizedFlagError(Error):
79
+ """Raised when a flag is unrecognized.
80
+
81
+ Attributes:
82
+ flagname: str, the name of the unrecognized flag.
83
+ flagvalue: The value of the flag, empty if the flag is not defined.
84
+ """
85
+
86
+ def __init__(self, flagname, flagvalue='', suggestions=None):
87
+ self.flagname = flagname
88
+ self.flagvalue = flagvalue
89
+ if suggestions:
90
+ # Space before the question mark is intentional to not include it in the
91
+ # selection when copy-pasting the suggestion from (some) terminals.
92
+ tip = '. Did you mean: %s ?' % ', '.join(suggestions)
93
+ else:
94
+ tip = ''
95
+ super(UnrecognizedFlagError, self).__init__(
96
+ 'Unknown command line flag \'%s\'%s' % (flagname, tip))
97
+
98
+
99
+ class UnparsedFlagAccessError(Error):
100
+ """Raised when accessing the flag value from unparsed :class:`FlagValues`."""
101
+
102
+
103
+ class ValidationError(Error):
104
+ """Raised when flag validator constraint is not satisfied."""
105
+
106
+
107
+ class FlagNameConflictsWithMethodError(Error):
108
+ """Raised when a flag name conflicts with :class:`FlagValues` methods."""
MLPY/Lib/site-packages/absl/flags/_flag.py ADDED
@@ -0,0 +1,556 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2017 The Abseil Authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Contains Flag class - information about single command-line flag.
16
+
17
+ Do NOT import this module directly. Import the flags package and use the
18
+ aliases defined at the package level instead.
19
+ """
20
+
21
+ from collections import abc
22
+ import copy
23
+ import enum
24
+ import functools
25
+ from typing import Any, Dict, Generic, Iterable, List, Optional, Text, Type, TypeVar, Union
26
+ from xml.dom import minidom
27
+
28
+ from absl.flags import _argument_parser
29
+ from absl.flags import _exceptions
30
+ from absl.flags import _helpers
31
+
32
+ _T = TypeVar('_T')
33
+ _ET = TypeVar('_ET', bound=enum.Enum)
34
+
35
+
36
+ @functools.total_ordering
37
+ class Flag(Generic[_T]):
38
+ """Information about a command-line flag.
39
+
40
+ Attributes:
41
+ name: the name for this flag
42
+ default: the default value for this flag
43
+ default_unparsed: the unparsed default value for this flag.
44
+ default_as_str: default value as repr'd string, e.g., "'true'"
45
+ (or None)
46
+ value: the most recent parsed value of this flag set by :meth:`parse`
47
+ help: a help string or None if no help is available
48
+ short_name: the single letter alias for this flag (or None)
49
+ boolean: if 'true', this flag does not accept arguments
50
+ present: true if this flag was parsed from command line flags
51
+ parser: an :class:`~absl.flags.ArgumentParser` object
52
+ serializer: an ArgumentSerializer object
53
+ allow_override: the flag may be redefined without raising an error,
54
+ and newly defined flag overrides the old one.
55
+ allow_override_cpp: use the flag from C++ if available the flag
56
+ definition is replaced by the C++ flag after init
57
+ allow_hide_cpp: use the Python flag despite having a C++ flag with
58
+ the same name (ignore the C++ flag)
59
+ using_default_value: the flag value has not been set by user
60
+ allow_overwrite: the flag may be parsed more than once without
61
+ raising an error, the last set value will be used
62
+ allow_using_method_names: whether this flag can be defined even if
63
+ it has a name that conflicts with a FlagValues method.
64
+ validators: list of the flag validators.
65
+
66
+ The only public method of a ``Flag`` object is :meth:`parse`, but it is
67
+ typically only called by a :class:`~absl.flags.FlagValues` object. The
68
+ :meth:`parse` method is a thin wrapper around the
69
+ :meth:`ArgumentParser.parse()<absl.flags.ArgumentParser.parse>` method. The
70
+ parsed value is saved in ``.value``, and the ``.present`` attribute is
71
+ updated. If this flag was already present, an Error is raised.
72
+
73
+ :meth:`parse` is also called during ``__init__`` to parse the default value
74
+ and initialize the ``.value`` attribute. This enables other python modules to
75
+ safely use flags even if the ``__main__`` module neglects to parse the
76
+ command line arguments. The ``.present`` attribute is cleared after
77
+ ``__init__`` parsing. If the default value is set to ``None``, then the
78
+ ``__init__`` parsing step is skipped and the ``.value`` attribute is
79
+ initialized to None.
80
+
81
+ Note: The default value is also presented to the user in the help
82
+ string, so it is important that it be a legal value for this flag.
83
+ """
84
+
85
+ # NOTE: pytype doesn't find defaults without this.
86
+ default: Optional[_T]
87
+ default_as_str: Optional[Text]
88
+ default_unparsed: Union[Optional[_T], Text]
89
+
90
+ def __init__(
91
+ self,
92
+ parser: _argument_parser.ArgumentParser[_T],
93
+ serializer: Optional[_argument_parser.ArgumentSerializer[_T]],
94
+ name: Text,
95
+ default: Union[Optional[_T], Text],
96
+ help_string: Optional[Text],
97
+ short_name: Optional[Text] = None,
98
+ boolean: bool = False,
99
+ allow_override: bool = False,
100
+ allow_override_cpp: bool = False,
101
+ allow_hide_cpp: bool = False,
102
+ allow_overwrite: bool = True,
103
+ allow_using_method_names: bool = False,
104
+ ) -> None:
105
+ self.name = name
106
+
107
+ if not help_string:
108
+ help_string = '(no help available)'
109
+
110
+ self.help = help_string
111
+ self.short_name = short_name
112
+ self.boolean = boolean
113
+ self.present = 0
114
+ self.parser = parser
115
+ self.serializer = serializer
116
+ self.allow_override = allow_override
117
+ self.allow_override_cpp = allow_override_cpp
118
+ self.allow_hide_cpp = allow_hide_cpp
119
+ self.allow_overwrite = allow_overwrite
120
+ self.allow_using_method_names = allow_using_method_names
121
+
122
+ self.using_default_value = True
123
+ self._value = None
124
+ self.validators = []
125
+ if self.allow_hide_cpp and self.allow_override_cpp:
126
+ raise _exceptions.Error(
127
+ "Can't have both allow_hide_cpp (means use Python flag) and "
128
+ 'allow_override_cpp (means use C++ flag after InitGoogle)')
129
+
130
+ self._set_default(default)
131
+
132
+ @property
133
+ def value(self) -> Optional[_T]:
134
+ return self._value
135
+
136
+ @value.setter
137
+ def value(self, value: Optional[_T]):
138
+ self._value = value
139
+
140
+ def __hash__(self):
141
+ return hash(id(self))
142
+
143
+ def __eq__(self, other):
144
+ return self is other
145
+
146
+ def __lt__(self, other):
147
+ if isinstance(other, Flag):
148
+ return id(self) < id(other)
149
+ return NotImplemented
150
+
151
+ def __bool__(self):
152
+ raise TypeError('A Flag instance would always be True. '
153
+ 'Did you mean to test the `.value` attribute?')
154
+
155
+ def __getstate__(self):
156
+ raise TypeError("can't pickle Flag objects")
157
+
158
+ def __copy__(self):
159
+ raise TypeError('%s does not support shallow copies. '
160
+ 'Use copy.deepcopy instead.' % type(self).__name__)
161
+
162
+ def __deepcopy__(self, memo: Dict[int, Any]) -> 'Flag[_T]':
163
+ result = object.__new__(type(self))
164
+ result.__dict__ = copy.deepcopy(self.__dict__, memo)
165
+ return result
166
+
167
+ def _get_parsed_value_as_string(self, value: Optional[_T]) -> Optional[Text]:
168
+ """Returns parsed flag value as string."""
169
+ if value is None:
170
+ return None
171
+ if self.serializer:
172
+ return repr(self.serializer.serialize(value))
173
+ if self.boolean:
174
+ if value:
175
+ return repr('true')
176
+ else:
177
+ return repr('false')
178
+ return repr(str(value))
179
+
180
+ def parse(self, argument: Union[Text, Optional[_T]]) -> None:
181
+ """Parses string and sets flag value.
182
+
183
+ Args:
184
+ argument: str or the correct flag value type, argument to be parsed.
185
+ """
186
+ if self.present and not self.allow_overwrite:
187
+ raise _exceptions.IllegalFlagValueError(
188
+ 'flag --%s=%s: already defined as %s' % (
189
+ self.name, argument, self.value))
190
+ self.value = self._parse(argument)
191
+ self.present += 1
192
+
193
+ def _parse(self, argument: Union[Text, _T]) -> Optional[_T]:
194
+ """Internal parse function.
195
+
196
+ It returns the parsed value, and does not modify class states.
197
+
198
+ Args:
199
+ argument: str or the correct flag value type, argument to be parsed.
200
+
201
+ Returns:
202
+ The parsed value.
203
+ """
204
+ try:
205
+ return self.parser.parse(argument)
206
+ except (TypeError, ValueError) as e: # Recast as IllegalFlagValueError.
207
+ raise _exceptions.IllegalFlagValueError(
208
+ 'flag --%s=%s: %s' % (self.name, argument, e))
209
+
210
+ def unparse(self) -> None:
211
+ self.value = self.default
212
+ self.using_default_value = True
213
+ self.present = 0
214
+
215
+ def serialize(self) -> Text:
216
+ """Serializes the flag."""
217
+ return self._serialize(self.value)
218
+
219
+ def _serialize(self, value: Optional[_T]) -> Text:
220
+ """Internal serialize function."""
221
+ if value is None:
222
+ return ''
223
+ if self.boolean:
224
+ if value:
225
+ return '--%s' % self.name
226
+ else:
227
+ return '--no%s' % self.name
228
+ else:
229
+ if not self.serializer:
230
+ raise _exceptions.Error(
231
+ 'Serializer not present for flag %s' % self.name)
232
+ return '--%s=%s' % (self.name, self.serializer.serialize(value))
233
+
234
+ def _set_default(self, value: Union[Optional[_T], Text]) -> None:
235
+ """Changes the default value (and current value too) for this Flag."""
236
+ self.default_unparsed = value
237
+ if value is None:
238
+ self.default = None
239
+ else:
240
+ self.default = self._parse_from_default(value)
241
+ self.default_as_str = self._get_parsed_value_as_string(self.default)
242
+ if self.using_default_value:
243
+ self.value = self.default
244
+
245
+ # This is split out so that aliases can skip regular parsing of the default
246
+ # value.
247
+ def _parse_from_default(self, value: Union[Text, _T]) -> Optional[_T]:
248
+ return self._parse(value)
249
+
250
+ def flag_type(self) -> Text:
251
+ """Returns a str that describes the type of the flag.
252
+
253
+ NOTE: we use strings, and not the types.*Type constants because
254
+ our flags can have more exotic types, e.g., 'comma separated list
255
+ of strings', 'whitespace separated list of strings', etc.
256
+ """
257
+ return self.parser.flag_type()
258
+
259
+ def _create_xml_dom_element(
260
+ self, doc: minidom.Document, module_name: str, is_key: bool = False
261
+ ) -> minidom.Element:
262
+ """Returns an XML element that contains this flag's information.
263
+
264
+ This is information that is relevant to all flags (e.g., name,
265
+ meaning, etc.). If you defined a flag that has some other pieces of
266
+ info, then please override _ExtraXMLInfo.
267
+
268
+ Please do NOT override this method.
269
+
270
+ Args:
271
+ doc: minidom.Document, the DOM document it should create nodes from.
272
+ module_name: str,, the name of the module that defines this flag.
273
+ is_key: boolean, True iff this flag is key for main module.
274
+
275
+ Returns:
276
+ A minidom.Element instance.
277
+ """
278
+ element = doc.createElement('flag')
279
+ if is_key:
280
+ element.appendChild(_helpers.create_xml_dom_element(doc, 'key', 'yes'))
281
+ element.appendChild(_helpers.create_xml_dom_element(
282
+ doc, 'file', module_name))
283
+ # Adds flag features that are relevant for all flags.
284
+ element.appendChild(_helpers.create_xml_dom_element(doc, 'name', self.name))
285
+ if self.short_name:
286
+ element.appendChild(_helpers.create_xml_dom_element(
287
+ doc, 'short_name', self.short_name))
288
+ if self.help:
289
+ element.appendChild(_helpers.create_xml_dom_element(
290
+ doc, 'meaning', self.help))
291
+ # The default flag value can either be represented as a string like on the
292
+ # command line, or as a Python object. We serialize this value in the
293
+ # latter case in order to remain consistent.
294
+ if self.serializer and not isinstance(self.default, str):
295
+ if self.default is not None:
296
+ default_serialized = self.serializer.serialize(self.default)
297
+ else:
298
+ default_serialized = ''
299
+ else:
300
+ default_serialized = self.default
301
+ element.appendChild(_helpers.create_xml_dom_element(
302
+ doc, 'default', default_serialized))
303
+ value_serialized = self._serialize_value_for_xml(self.value)
304
+ element.appendChild(_helpers.create_xml_dom_element(
305
+ doc, 'current', value_serialized))
306
+ element.appendChild(_helpers.create_xml_dom_element(
307
+ doc, 'type', self.flag_type()))
308
+ # Adds extra flag features this flag may have.
309
+ for e in self._extra_xml_dom_elements(doc):
310
+ element.appendChild(e)
311
+ return element
312
+
313
+ def _serialize_value_for_xml(self, value: Optional[_T]) -> Any:
314
+ """Returns the serialized value, for use in an XML help text."""
315
+ return value
316
+
317
+ def _extra_xml_dom_elements(
318
+ self, doc: minidom.Document
319
+ ) -> List[minidom.Element]:
320
+ """Returns extra info about this flag in XML.
321
+
322
+ "Extra" means "not already included by _create_xml_dom_element above."
323
+
324
+ Args:
325
+ doc: minidom.Document, the DOM document it should create nodes from.
326
+
327
+ Returns:
328
+ A list of minidom.Element.
329
+ """
330
+ # Usually, the parser knows the extra details about the flag, so
331
+ # we just forward the call to it.
332
+ return self.parser._custom_xml_dom_elements(doc) # pylint: disable=protected-access
333
+
334
+
335
+ class BooleanFlag(Flag[bool]):
336
+ """Basic boolean flag.
337
+
338
+ Boolean flags do not take any arguments, and their value is either
339
+ ``True`` (1) or ``False`` (0). The false value is specified on the command
340
+ line by prepending the word ``'no'`` to either the long or the short flag
341
+ name.
342
+
343
+ For example, if a Boolean flag was created whose long name was
344
+ ``'update'`` and whose short name was ``'x'``, then this flag could be
345
+ explicitly unset through either ``--noupdate`` or ``--nox``.
346
+ """
347
+
348
+ def __init__(
349
+ self,
350
+ name: Text,
351
+ default: Union[Optional[bool], Text],
352
+ help: Optional[Text], # pylint: disable=redefined-builtin
353
+ short_name: Optional[Text] = None,
354
+ **args
355
+ ) -> None:
356
+ p = _argument_parser.BooleanParser()
357
+ super(BooleanFlag, self).__init__(
358
+ p, None, name, default, help, short_name, True, **args
359
+ )
360
+
361
+
362
+ class EnumFlag(Flag[Text]):
363
+ """Basic enum flag; its value can be any string from list of enum_values."""
364
+
365
+ def __init__(
366
+ self,
367
+ name: Text,
368
+ default: Optional[Text],
369
+ help: Optional[Text], # pylint: disable=redefined-builtin
370
+ enum_values: Iterable[Text],
371
+ short_name: Optional[Text] = None,
372
+ case_sensitive: bool = True,
373
+ **args
374
+ ):
375
+ p = _argument_parser.EnumParser(enum_values, case_sensitive)
376
+ g = _argument_parser.ArgumentSerializer()
377
+ super(EnumFlag, self).__init__(
378
+ p, g, name, default, help, short_name, **args)
379
+ # NOTE: parser should be typed EnumParser but the constructor
380
+ # restricts the available interface to ArgumentParser[str].
381
+ self.parser = p
382
+ self.help = '<%s>: %s' % ('|'.join(p.enum_values), self.help)
383
+
384
+ def _extra_xml_dom_elements(
385
+ self, doc: minidom.Document
386
+ ) -> List[minidom.Element]:
387
+ elements = []
388
+ for enum_value in self.parser.enum_values:
389
+ elements.append(_helpers.create_xml_dom_element(
390
+ doc, 'enum_value', enum_value))
391
+ return elements
392
+
393
+
394
+ class EnumClassFlag(Flag[_ET]):
395
+ """Basic enum flag; its value is an enum class's member."""
396
+
397
+ def __init__(
398
+ self,
399
+ name: Text,
400
+ default: Union[Optional[_ET], Text],
401
+ help: Optional[Text], # pylint: disable=redefined-builtin
402
+ enum_class: Type[_ET],
403
+ short_name: Optional[Text] = None,
404
+ case_sensitive: bool = False,
405
+ **args
406
+ ):
407
+ p = _argument_parser.EnumClassParser(
408
+ enum_class, case_sensitive=case_sensitive)
409
+ g = _argument_parser.EnumClassSerializer(lowercase=not case_sensitive)
410
+ super(EnumClassFlag, self).__init__(
411
+ p, g, name, default, help, short_name, **args)
412
+ # NOTE: parser should be typed EnumClassParser[_ET] but the constructor
413
+ # restricts the available interface to ArgumentParser[_ET].
414
+ self.parser = p
415
+ self.help = '<%s>: %s' % ('|'.join(p.member_names), self.help)
416
+
417
+ def _extra_xml_dom_elements(
418
+ self, doc: minidom.Document
419
+ ) -> List[minidom.Element]:
420
+ elements = []
421
+ for enum_value in self.parser.enum_class.__members__.keys():
422
+ elements.append(_helpers.create_xml_dom_element(
423
+ doc, 'enum_value', enum_value))
424
+ return elements
425
+
426
+
427
+ class MultiFlag(Generic[_T], Flag[List[_T]]):
428
+ """A flag that can appear multiple time on the command-line.
429
+
430
+ The value of such a flag is a list that contains the individual values
431
+ from all the appearances of that flag on the command-line.
432
+
433
+ See the __doc__ for Flag for most behavior of this class. Only
434
+ differences in behavior are described here:
435
+
436
+ * The default value may be either a single value or an iterable of values.
437
+ A single value is transformed into a single-item list of that value.
438
+
439
+ * The value of the flag is always a list, even if the option was
440
+ only supplied once, and even if the default value is a single
441
+ value
442
+ """
443
+
444
+ def __init__(self, *args, **kwargs):
445
+ super(MultiFlag, self).__init__(*args, **kwargs)
446
+ self.help += ';\n repeat this option to specify a list of values'
447
+
448
+ def parse(self, arguments: Union[Text, _T, Iterable[_T]]): # pylint: disable=arguments-renamed
449
+ """Parses one or more arguments with the installed parser.
450
+
451
+ Args:
452
+ arguments: a single argument or a list of arguments (typically a
453
+ list of default values); a single argument is converted
454
+ internally into a list containing one item.
455
+ """
456
+ new_values = self._parse(arguments)
457
+ if self.present:
458
+ self.value.extend(new_values)
459
+ else:
460
+ self.value = new_values
461
+ self.present += len(new_values)
462
+
463
+ def _parse(self, arguments: Union[Text, Optional[Iterable[_T]]]) -> List[_T]: # pylint: disable=arguments-renamed
464
+ if (isinstance(arguments, abc.Iterable) and
465
+ not isinstance(arguments, str)):
466
+ arguments = list(arguments)
467
+
468
+ if not isinstance(arguments, list):
469
+ # Default value may be a list of values. Most other arguments
470
+ # will not be, so convert them into a single-item list to make
471
+ # processing simpler below.
472
+ arguments = [arguments]
473
+
474
+ return [super(MultiFlag, self)._parse(item) for item in arguments]
475
+
476
+ def _serialize(self, value: Optional[List[_T]]) -> Text:
477
+ """See base class."""
478
+ if not self.serializer:
479
+ raise _exceptions.Error(
480
+ 'Serializer not present for flag %s' % self.name)
481
+ if value is None:
482
+ return ''
483
+
484
+ serialized_items = [
485
+ super(MultiFlag, self)._serialize(value_item) for value_item in value
486
+ ]
487
+
488
+ return '\n'.join(serialized_items)
489
+
490
+ def flag_type(self):
491
+ """See base class."""
492
+ return 'multi ' + self.parser.flag_type()
493
+
494
+ def _extra_xml_dom_elements(
495
+ self, doc: minidom.Document
496
+ ) -> List[minidom.Element]:
497
+ elements = []
498
+ if hasattr(self.parser, 'enum_values'):
499
+ for enum_value in self.parser.enum_values: # pytype: disable=attribute-error
500
+ elements.append(_helpers.create_xml_dom_element(
501
+ doc, 'enum_value', enum_value))
502
+ return elements
503
+
504
+
505
+ class MultiEnumClassFlag(MultiFlag[_ET]): # pytype: disable=not-indexable
506
+ """A multi_enum_class flag.
507
+
508
+ See the __doc__ for MultiFlag for most behaviors of this class. In addition,
509
+ this class knows how to handle enum.Enum instances as values for this flag
510
+ type.
511
+ """
512
+
513
+ def __init__(
514
+ self,
515
+ name: str,
516
+ default: Union[None, Iterable[_ET], _ET, Iterable[Text], Text],
517
+ help_string: str,
518
+ enum_class: Type[_ET],
519
+ case_sensitive: bool = False,
520
+ **args
521
+ ):
522
+ p = _argument_parser.EnumClassParser(
523
+ enum_class, case_sensitive=case_sensitive)
524
+ g = _argument_parser.EnumClassListSerializer(
525
+ list_sep=',', lowercase=not case_sensitive)
526
+ super(MultiEnumClassFlag, self).__init__(
527
+ p, g, name, default, help_string, **args)
528
+ # NOTE: parser should be typed EnumClassParser[_ET] but the constructor
529
+ # restricts the available interface to ArgumentParser[str].
530
+ self.parser = p
531
+ # NOTE: serializer should be non-Optional but this isn't inferred.
532
+ self.serializer = g
533
+ self.help = (
534
+ '<%s>: %s;\n repeat this option to specify a list of values' %
535
+ ('|'.join(p.member_names), help_string or '(no help available)'))
536
+
537
+ def _extra_xml_dom_elements(
538
+ self, doc: minidom.Document
539
+ ) -> List[minidom.Element]:
540
+ elements = []
541
+ for enum_value in self.parser.enum_class.__members__.keys(): # pytype: disable=attribute-error
542
+ elements.append(_helpers.create_xml_dom_element(
543
+ doc, 'enum_value', enum_value))
544
+ return elements
545
+
546
+ def _serialize_value_for_xml(self, value):
547
+ """See base class."""
548
+ if value is not None:
549
+ if not self.serializer:
550
+ raise _exceptions.Error(
551
+ 'Serializer not present for flag %s' % self.name
552
+ )
553
+ value_serialized = self.serializer.serialize(value)
554
+ else:
555
+ value_serialized = ''
556
+ return value_serialized
MLPY/Lib/site-packages/absl/flags/_flagvalues.py ADDED
@@ -0,0 +1,1480 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2017 The Abseil Authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """Defines the FlagValues class - registry of 'Flag' objects.
15
+
16
+ Do NOT import this module directly. Import the flags package and use the
17
+ aliases defined at the package level instead.
18
+ """
19
+
20
+ import copy
21
+ import itertools
22
+ import logging
23
+ import os
24
+ import sys
25
+ from typing import Any, Callable, Dict, Iterable, Iterator, List, Optional, Sequence, Text, TextIO, Generic, TypeVar, Union, Tuple
26
+ from xml.dom import minidom
27
+
28
+ from absl.flags import _exceptions
29
+ from absl.flags import _flag
30
+ from absl.flags import _helpers
31
+ from absl.flags import _validators_classes
32
+ from absl.flags._flag import Flag
33
+
34
+ # Add flagvalues module to disclaimed module ids.
35
+ _helpers.disclaim_module_ids.add(id(sys.modules[__name__]))
36
+
37
+ _T = TypeVar('_T')
38
+
39
+
40
+ class FlagValues:
41
+ """Registry of :class:`~absl.flags.Flag` objects.
42
+
43
+ A :class:`FlagValues` can then scan command line arguments, passing flag
44
+ arguments through to the 'Flag' objects that it owns. It also
45
+ provides easy access to the flag values. Typically only one
46
+ :class:`FlagValues` object is needed by an application:
47
+ :const:`FLAGS`.
48
+
49
+ This class is heavily overloaded:
50
+
51
+ :class:`Flag` objects are registered via ``__setitem__``::
52
+
53
+ FLAGS['longname'] = x # register a new flag
54
+
55
+ The ``.value`` attribute of the registered :class:`~absl.flags.Flag` objects
56
+ can be accessed as attributes of this :class:`FlagValues` object, through
57
+ ``__getattr__``. Both the long and short name of the original
58
+ :class:`~absl.flags.Flag` objects can be used to access its value::
59
+
60
+ FLAGS.longname # parsed flag value
61
+ FLAGS.x # parsed flag value (short name)
62
+
63
+ Command line arguments are scanned and passed to the registered
64
+ :class:`~absl.flags.Flag` objects through the ``__call__`` method. Unparsed
65
+ arguments, including ``argv[0]`` (e.g. the program name) are returned::
66
+
67
+ argv = FLAGS(sys.argv) # scan command line arguments
68
+
69
+ The original registered :class:`~absl.flags.Flag` objects can be retrieved
70
+ through the use of the dictionary-like operator, ``__getitem__``::
71
+
72
+ x = FLAGS['longname'] # access the registered Flag object
73
+
74
+ The ``str()`` operator of a :class:`absl.flags.FlagValues` object provides
75
+ help for all of the registered :class:`~absl.flags.Flag` objects.
76
+ """
77
+
78
+ _HAS_DYNAMIC_ATTRIBUTES = True
79
+
80
+ # A note on collections.abc.Mapping:
81
+ # FlagValues defines __getitem__, __iter__, and __len__. It makes perfect
82
+ # sense to let it be a collections.abc.Mapping class. However, we are not
83
+ # able to do so. The mixin methods, e.g. keys, values, are not uncommon flag
84
+ # names. Those flag values would not be accessible via the FLAGS.xxx form.
85
+
86
+ __dict__: Dict[str, Any]
87
+
88
+ def __init__(self):
89
+ # Since everything in this class is so heavily overloaded, the only
90
+ # way of defining and using fields is to access __dict__ directly.
91
+
92
+ # Dictionary: flag name (string) -> Flag object.
93
+ self.__dict__['__flags'] = {}
94
+
95
+ # Set: name of hidden flag (string).
96
+ # Holds flags that should not be directly accessible from Python.
97
+ self.__dict__['__hiddenflags'] = set()
98
+
99
+ # Dictionary: module name (string) -> list of Flag objects that are defined
100
+ # by that module.
101
+ self.__dict__['__flags_by_module'] = {}
102
+ # Dictionary: module id (int) -> list of Flag objects that are defined by
103
+ # that module.
104
+ self.__dict__['__flags_by_module_id'] = {}
105
+ # Dictionary: module name (string) -> list of Flag objects that are
106
+ # key for that module.
107
+ self.__dict__['__key_flags_by_module'] = {}
108
+
109
+ # Bool: True if flags were parsed.
110
+ self.__dict__['__flags_parsed'] = False
111
+
112
+ # Bool: True if unparse_flags() was called.
113
+ self.__dict__['__unparse_flags_called'] = False
114
+
115
+ # None or Method(name, value) to call from __setattr__ for an unknown flag.
116
+ self.__dict__['__set_unknown'] = None
117
+
118
+ # A set of banned flag names. This is to prevent users from accidentally
119
+ # defining a flag that has the same name as a method on this class.
120
+ # Users can still allow defining the flag by passing
121
+ # allow_using_method_names=True in DEFINE_xxx functions.
122
+ self.__dict__['__banned_flag_names'] = frozenset(dir(FlagValues))
123
+
124
+ # Bool: Whether to use GNU style scanning.
125
+ self.__dict__['__use_gnu_getopt'] = True
126
+
127
+ # Bool: Whether use_gnu_getopt has been explicitly set by the user.
128
+ self.__dict__['__use_gnu_getopt_explicitly_set'] = False
129
+
130
+ # Function: Takes a flag name as parameter, returns a tuple
131
+ # (is_retired, type_is_bool).
132
+ self.__dict__['__is_retired_flag_func'] = None
133
+
134
+ def set_gnu_getopt(self, gnu_getopt: bool = True) -> None:
135
+ """Sets whether or not to use GNU style scanning.
136
+
137
+ GNU style allows mixing of flag and non-flag arguments. See
138
+ http://docs.python.org/library/getopt.html#getopt.gnu_getopt
139
+
140
+ Args:
141
+ gnu_getopt: bool, whether or not to use GNU style scanning.
142
+ """
143
+ self.__dict__['__use_gnu_getopt'] = gnu_getopt
144
+ self.__dict__['__use_gnu_getopt_explicitly_set'] = True
145
+
146
+ def is_gnu_getopt(self) -> bool:
147
+ return self.__dict__['__use_gnu_getopt']
148
+
149
+ def _flags(self) -> Dict[Text, Flag]:
150
+ return self.__dict__['__flags']
151
+
152
+ def flags_by_module_dict(self) -> Dict[Text, List[Flag]]:
153
+ """Returns the dictionary of module_name -> list of defined flags.
154
+
155
+ Returns:
156
+ A dictionary. Its keys are module names (strings). Its values
157
+ are lists of Flag objects.
158
+ """
159
+ return self.__dict__['__flags_by_module']
160
+
161
+ def flags_by_module_id_dict(self) -> Dict[int, List[Flag]]:
162
+ """Returns the dictionary of module_id -> list of defined flags.
163
+
164
+ Returns:
165
+ A dictionary. Its keys are module IDs (ints). Its values
166
+ are lists of Flag objects.
167
+ """
168
+ return self.__dict__['__flags_by_module_id']
169
+
170
+ def key_flags_by_module_dict(self) -> Dict[Text, List[Flag]]:
171
+ """Returns the dictionary of module_name -> list of key flags.
172
+
173
+ Returns:
174
+ A dictionary. Its keys are module names (strings). Its values
175
+ are lists of Flag objects.
176
+ """
177
+ return self.__dict__['__key_flags_by_module']
178
+
179
+ def register_flag_by_module(self, module_name: Text, flag: Flag) -> None:
180
+ """Records the module that defines a specific flag.
181
+
182
+ We keep track of which flag is defined by which module so that we
183
+ can later sort the flags by module.
184
+
185
+ Args:
186
+ module_name: str, the name of a Python module.
187
+ flag: Flag, the Flag instance that is key to the module.
188
+ """
189
+ flags_by_module = self.flags_by_module_dict()
190
+ flags_by_module.setdefault(module_name, []).append(flag)
191
+
192
+ def register_flag_by_module_id(self, module_id: int, flag: Flag) -> None:
193
+ """Records the module that defines a specific flag.
194
+
195
+ Args:
196
+ module_id: int, the ID of the Python module.
197
+ flag: Flag, the Flag instance that is key to the module.
198
+ """
199
+ flags_by_module_id = self.flags_by_module_id_dict()
200
+ flags_by_module_id.setdefault(module_id, []).append(flag)
201
+
202
+ def register_key_flag_for_module(self, module_name: Text, flag: Flag) -> None:
203
+ """Specifies that a flag is a key flag for a module.
204
+
205
+ Args:
206
+ module_name: str, the name of a Python module.
207
+ flag: Flag, the Flag instance that is key to the module.
208
+ """
209
+ key_flags_by_module = self.key_flags_by_module_dict()
210
+ # The list of key flags for the module named module_name.
211
+ key_flags = key_flags_by_module.setdefault(module_name, [])
212
+ # Add flag, but avoid duplicates.
213
+ if flag not in key_flags:
214
+ key_flags.append(flag)
215
+
216
+ def _flag_is_registered(self, flag_obj: Flag) -> bool:
217
+ """Checks whether a Flag object is registered under long name or short name.
218
+
219
+ Args:
220
+ flag_obj: Flag, the Flag instance to check for.
221
+
222
+ Returns:
223
+ bool, True iff flag_obj is registered under long name or short name.
224
+ """
225
+ flag_dict = self._flags()
226
+ # Check whether flag_obj is registered under its long name.
227
+ name = flag_obj.name
228
+ if flag_dict.get(name, None) == flag_obj:
229
+ return True
230
+ # Check whether flag_obj is registered under its short name.
231
+ short_name = flag_obj.short_name
232
+ if (short_name is not None and flag_dict.get(short_name, None) == flag_obj):
233
+ return True
234
+ return False
235
+
236
+ def _cleanup_unregistered_flag_from_module_dicts(
237
+ self, flag_obj: Flag
238
+ ) -> None:
239
+ """Cleans up unregistered flags from all module -> [flags] dictionaries.
240
+
241
+ If flag_obj is registered under either its long name or short name, it
242
+ won't be removed from the dictionaries.
243
+
244
+ Args:
245
+ flag_obj: Flag, the Flag instance to clean up for.
246
+ """
247
+ if self._flag_is_registered(flag_obj):
248
+ return
249
+ for flags_by_module_dict in (self.flags_by_module_dict(),
250
+ self.flags_by_module_id_dict(),
251
+ self.key_flags_by_module_dict()):
252
+ for flags_in_module in flags_by_module_dict.values():
253
+ # While (as opposed to if) takes care of multiple occurrences of a
254
+ # flag in the list for the same module.
255
+ while flag_obj in flags_in_module:
256
+ flags_in_module.remove(flag_obj)
257
+
258
+ def get_flags_for_module(self, module: Union[Text, Any]) -> List[Flag]:
259
+ """Returns the list of flags defined by a module.
260
+
261
+ Args:
262
+ module: module|str, the module to get flags from.
263
+
264
+ Returns:
265
+ [Flag], a new list of Flag instances. Caller may update this list as
266
+ desired: none of those changes will affect the internals of this
267
+ FlagValue instance.
268
+ """
269
+ if not isinstance(module, str):
270
+ module = module.__name__
271
+ if module == '__main__':
272
+ module = sys.argv[0]
273
+
274
+ return list(self.flags_by_module_dict().get(module, []))
275
+
276
+ def get_key_flags_for_module(self, module: Union[Text, Any]) -> List[Flag]:
277
+ """Returns the list of key flags for a module.
278
+
279
+ Args:
280
+ module: module|str, the module to get key flags from.
281
+
282
+ Returns:
283
+ [Flag], a new list of Flag instances. Caller may update this list as
284
+ desired: none of those changes will affect the internals of this
285
+ FlagValue instance.
286
+ """
287
+ if not isinstance(module, str):
288
+ module = module.__name__
289
+ if module == '__main__':
290
+ module = sys.argv[0]
291
+
292
+ # Any flag is a key flag for the module that defined it. NOTE:
293
+ # key_flags is a fresh list: we can update it without affecting the
294
+ # internals of this FlagValues object.
295
+ key_flags = self.get_flags_for_module(module)
296
+
297
+ # Take into account flags explicitly declared as key for a module.
298
+ for flag in self.key_flags_by_module_dict().get(module, []):
299
+ if flag not in key_flags:
300
+ key_flags.append(flag)
301
+ return key_flags
302
+
303
+ # TODO(yileiyang): Restrict default to Optional[Text].
304
+ def find_module_defining_flag(
305
+ self, flagname: Text, default: Optional[_T] = None
306
+ ) -> Union[str, Optional[_T]]:
307
+ """Return the name of the module defining this flag, or default.
308
+
309
+ Args:
310
+ flagname: str, name of the flag to lookup.
311
+ default: Value to return if flagname is not defined. Defaults to None.
312
+
313
+ Returns:
314
+ The name of the module which registered the flag with this name.
315
+ If no such module exists (i.e. no flag with this name exists),
316
+ we return default.
317
+ """
318
+ registered_flag = self._flags().get(flagname)
319
+ if registered_flag is None:
320
+ return default
321
+ for module, flags in self.flags_by_module_dict().items():
322
+ for flag in flags:
323
+ # It must compare the flag with the one in _flags. This is because a
324
+ # flag might be overridden only for its long name (or short name),
325
+ # and only its short name (or long name) is considered registered.
326
+ if (flag.name == registered_flag.name and
327
+ flag.short_name == registered_flag.short_name):
328
+ return module
329
+ return default
330
+
331
+ # TODO(yileiyang): Restrict default to Optional[Text].
332
+ def find_module_id_defining_flag(
333
+ self, flagname: Text, default: Optional[_T] = None
334
+ ) -> Union[int, Optional[_T]]:
335
+ """Return the ID of the module defining this flag, or default.
336
+
337
+ Args:
338
+ flagname: str, name of the flag to lookup.
339
+ default: Value to return if flagname is not defined. Defaults to None.
340
+
341
+ Returns:
342
+ The ID of the module which registered the flag with this name.
343
+ If no such module exists (i.e. no flag with this name exists),
344
+ we return default.
345
+ """
346
+ registered_flag = self._flags().get(flagname)
347
+ if registered_flag is None:
348
+ return default
349
+ for module_id, flags in self.flags_by_module_id_dict().items():
350
+ for flag in flags:
351
+ # It must compare the flag with the one in _flags. This is because a
352
+ # flag might be overridden only for its long name (or short name),
353
+ # and only its short name (or long name) is considered registered.
354
+ if (flag.name == registered_flag.name and
355
+ flag.short_name == registered_flag.short_name):
356
+ return module_id
357
+ return default
358
+
359
+ def _register_unknown_flag_setter(
360
+ self, setter: Callable[[str, Any], None]
361
+ ) -> None:
362
+ """Allow set default values for undefined flags.
363
+
364
+ Args:
365
+ setter: Method(name, value) to call to __setattr__ an unknown flag. Must
366
+ raise NameError or ValueError for invalid name/value.
367
+ """
368
+ self.__dict__['__set_unknown'] = setter
369
+
370
+ def _set_unknown_flag(self, name: str, value: _T) -> _T:
371
+ """Returns value if setting flag |name| to |value| returned True.
372
+
373
+ Args:
374
+ name: str, name of the flag to set.
375
+ value: Value to set.
376
+
377
+ Returns:
378
+ Flag value on successful call.
379
+
380
+ Raises:
381
+ UnrecognizedFlagError
382
+ IllegalFlagValueError
383
+ """
384
+ setter = self.__dict__['__set_unknown']
385
+ if setter:
386
+ try:
387
+ setter(name, value)
388
+ return value
389
+ except (TypeError, ValueError): # Flag value is not valid.
390
+ raise _exceptions.IllegalFlagValueError(
391
+ '"{1}" is not valid for --{0}'.format(name, value))
392
+ except NameError: # Flag name is not valid.
393
+ pass
394
+ raise _exceptions.UnrecognizedFlagError(name, value)
395
+
396
+ def append_flag_values(self, flag_values: 'FlagValues') -> None:
397
+ """Appends flags registered in another FlagValues instance.
398
+
399
+ Args:
400
+ flag_values: FlagValues, the FlagValues instance from which to copy flags.
401
+ """
402
+ for flag_name, flag in flag_values._flags().items(): # pylint: disable=protected-access
403
+ # Each flags with short_name appears here twice (once under its
404
+ # normal name, and again with its short name). To prevent
405
+ # problems (DuplicateFlagError) with double flag registration, we
406
+ # perform a check to make sure that the entry we're looking at is
407
+ # for its normal name.
408
+ if flag_name == flag.name:
409
+ try:
410
+ self[flag_name] = flag
411
+ except _exceptions.DuplicateFlagError:
412
+ raise _exceptions.DuplicateFlagError.from_flag(
413
+ flag_name, self, other_flag_values=flag_values)
414
+
415
+ def remove_flag_values(
416
+ self, flag_values: 'Union[FlagValues, Iterable[Text]]'
417
+ ) -> None:
418
+ """Remove flags that were previously appended from another FlagValues.
419
+
420
+ Args:
421
+ flag_values: FlagValues, the FlagValues instance containing flags to
422
+ remove.
423
+ """
424
+ for flag_name in flag_values:
425
+ self.__delattr__(flag_name)
426
+
427
+ def __setitem__(self, name: Text, flag: Flag) -> None:
428
+ """Registers a new flag variable."""
429
+ fl = self._flags()
430
+ if not isinstance(flag, _flag.Flag):
431
+ raise _exceptions.IllegalFlagValueError(
432
+ f'Expect Flag instances, found type {type(flag)}. '
433
+ "Maybe you didn't mean to use FlagValue.__setitem__?")
434
+ if not isinstance(name, str):
435
+ raise _exceptions.Error('Flag name must be a string')
436
+ if not name:
437
+ raise _exceptions.Error('Flag name cannot be empty')
438
+ if ' ' in name:
439
+ raise _exceptions.Error('Flag name cannot contain a space')
440
+ self._check_method_name_conflicts(name, flag)
441
+ if name in fl and not flag.allow_override and not fl[name].allow_override:
442
+ module, module_name = _helpers.get_calling_module_object_and_name()
443
+ if (self.find_module_defining_flag(name) == module_name and
444
+ id(module) != self.find_module_id_defining_flag(name)):
445
+ # If the flag has already been defined by a module with the same name,
446
+ # but a different ID, we can stop here because it indicates that the
447
+ # module is simply being imported a subsequent time.
448
+ return
449
+ raise _exceptions.DuplicateFlagError.from_flag(name, self)
450
+ # If a new flag overrides an old one, we need to cleanup the old flag's
451
+ # modules if it's not registered.
452
+ flags_to_cleanup = set()
453
+ short_name: str = flag.short_name # pytype: disable=annotation-type-mismatch
454
+ if short_name is not None:
455
+ if (short_name in fl and not flag.allow_override and
456
+ not fl[short_name].allow_override):
457
+ raise _exceptions.DuplicateFlagError.from_flag(short_name, self)
458
+ if short_name in fl and fl[short_name] != flag:
459
+ flags_to_cleanup.add(fl[short_name])
460
+ fl[short_name] = flag
461
+ if (name not in fl # new flag
462
+ or fl[name].using_default_value or not flag.using_default_value):
463
+ if name in fl and fl[name] != flag:
464
+ flags_to_cleanup.add(fl[name])
465
+ fl[name] = flag
466
+ for f in flags_to_cleanup:
467
+ self._cleanup_unregistered_flag_from_module_dicts(f)
468
+
469
+ def __dir__(self) -> List[Text]:
470
+ """Returns list of names of all defined flags.
471
+
472
+ Useful for TAB-completion in ipython.
473
+
474
+ Returns:
475
+ [str], a list of names of all defined flags.
476
+ """
477
+ return sorted(self.__dict__['__flags'])
478
+
479
+ def __getitem__(self, name: Text) -> Flag:
480
+ """Returns the Flag object for the flag --name."""
481
+ return self._flags()[name]
482
+
483
+ def _hide_flag(self, name):
484
+ """Marks the flag --name as hidden."""
485
+ self.__dict__['__hiddenflags'].add(name)
486
+
487
+ def __getattr__(self, name: Text) -> Any:
488
+ """Retrieves the 'value' attribute of the flag --name."""
489
+ fl = self._flags()
490
+ if name not in fl:
491
+ raise AttributeError(name)
492
+ if name in self.__dict__['__hiddenflags']:
493
+ raise AttributeError(name)
494
+
495
+ if self.__dict__['__flags_parsed'] or fl[name].present:
496
+ return fl[name].value
497
+ else:
498
+ raise _exceptions.UnparsedFlagAccessError(
499
+ 'Trying to access flag --%s before flags were parsed.' % name)
500
+
501
+ def __setattr__(self, name: Text, value: _T) -> _T:
502
+ """Sets the 'value' attribute of the flag --name."""
503
+ self._set_attributes(**{name: value})
504
+ return value
505
+
506
+ def _set_attributes(self, **attributes: Any) -> None:
507
+ """Sets multiple flag values together, triggers validators afterwards."""
508
+ fl = self._flags()
509
+ known_flag_vals = {}
510
+ known_flag_used_defaults = {}
511
+ try:
512
+ for name, value in attributes.items():
513
+ if name in self.__dict__['__hiddenflags']:
514
+ raise AttributeError(name)
515
+ if name in fl:
516
+ orig = fl[name].value
517
+ fl[name].value = value
518
+ known_flag_vals[name] = orig
519
+ else:
520
+ self._set_unknown_flag(name, value)
521
+ for name in known_flag_vals:
522
+ self._assert_validators(fl[name].validators)
523
+ known_flag_used_defaults[name] = fl[name].using_default_value
524
+ fl[name].using_default_value = False
525
+ except:
526
+ for name, orig in known_flag_vals.items():
527
+ fl[name].value = orig
528
+ for name, orig in known_flag_used_defaults.items():
529
+ fl[name].using_default_value = orig
530
+ # NOTE: We do not attempt to undo unknown flag side effects because we
531
+ # cannot reliably undo the user-configured behavior.
532
+ raise
533
+
534
+ def validate_all_flags(self) -> None:
535
+ """Verifies whether all flags pass validation.
536
+
537
+ Raises:
538
+ AttributeError: Raised if validators work with a non-existing flag.
539
+ IllegalFlagValueError: Raised if validation fails for at least one
540
+ validator.
541
+ """
542
+ all_validators = set()
543
+ for flag in self._flags().values():
544
+ all_validators.update(flag.validators)
545
+ self._assert_validators(all_validators)
546
+
547
+ def _assert_validators(
548
+ self, validators: Iterable[_validators_classes.Validator]
549
+ ) -> None:
550
+ """Asserts if all validators in the list are satisfied.
551
+
552
+ It asserts validators in the order they were created.
553
+
554
+ Args:
555
+ validators: Iterable(validators.Validator), validators to be verified.
556
+
557
+ Raises:
558
+ AttributeError: Raised if validators work with a non-existing flag.
559
+ IllegalFlagValueError: Raised if validation fails for at least one
560
+ validator.
561
+ """
562
+ messages = []
563
+ bad_flags = set()
564
+ for validator in sorted(
565
+ validators, key=lambda validator: validator.insertion_index):
566
+ try:
567
+ if isinstance(validator, _validators_classes.SingleFlagValidator):
568
+ if validator.flag_name in bad_flags:
569
+ continue
570
+ elif isinstance(validator, _validators_classes.MultiFlagsValidator):
571
+ if bad_flags & set(validator.flag_names):
572
+ continue
573
+ validator.verify(self)
574
+ except _exceptions.ValidationError as e:
575
+ if isinstance(validator, _validators_classes.SingleFlagValidator):
576
+ bad_flags.add(validator.flag_name)
577
+ elif isinstance(validator, _validators_classes.MultiFlagsValidator):
578
+ bad_flags.update(set(validator.flag_names))
579
+ message = validator.print_flags_with_values(self)
580
+ messages.append('%s: %s' % (message, str(e)))
581
+ if messages:
582
+ raise _exceptions.IllegalFlagValueError('\n'.join(messages))
583
+
584
+ def __delattr__(self, flag_name: Text) -> None:
585
+ """Deletes a previously-defined flag from a flag object.
586
+
587
+ This method makes sure we can delete a flag by using
588
+
589
+ del FLAGS.<flag_name>
590
+
591
+ E.g.,
592
+
593
+ flags.DEFINE_integer('foo', 1, 'Integer flag.')
594
+ del flags.FLAGS.foo
595
+
596
+ If a flag is also registered by its the other name (long name or short
597
+ name), the other name won't be deleted.
598
+
599
+ Args:
600
+ flag_name: str, the name of the flag to be deleted.
601
+
602
+ Raises:
603
+ AttributeError: Raised when there is no registered flag named flag_name.
604
+ """
605
+ fl = self._flags()
606
+ if flag_name not in fl:
607
+ raise AttributeError(flag_name)
608
+
609
+ flag_obj = fl[flag_name]
610
+ del fl[flag_name]
611
+
612
+ self._cleanup_unregistered_flag_from_module_dicts(flag_obj)
613
+
614
+ def set_default(self, name: Text, value: Any) -> None:
615
+ """Changes the default value of the named flag object.
616
+
617
+ The flag's current value is also updated if the flag is currently using
618
+ the default value, i.e. not specified in the command line, and not set
619
+ by FLAGS.name = value.
620
+
621
+ Args:
622
+ name: str, the name of the flag to modify.
623
+ value: The new default value.
624
+
625
+ Raises:
626
+ UnrecognizedFlagError: Raised when there is no registered flag named name.
627
+ IllegalFlagValueError: Raised when value is not valid.
628
+ """
629
+ fl = self._flags()
630
+ if name not in fl:
631
+ self._set_unknown_flag(name, value)
632
+ return
633
+ fl[name]._set_default(value) # pylint: disable=protected-access
634
+ self._assert_validators(fl[name].validators)
635
+
636
+ def __contains__(self, name: Text) -> bool:
637
+ """Returns True if name is a value (flag) in the dict."""
638
+ return name in self._flags()
639
+
640
+ def __len__(self) -> int:
641
+ return len(self.__dict__['__flags'])
642
+
643
+ def __iter__(self) -> Iterator[Text]:
644
+ return iter(self._flags())
645
+
646
+ def __call__(
647
+ self, argv: Sequence[Text], known_only: bool = False
648
+ ) -> List[Text]:
649
+ """Parses flags from argv; stores parsed flags into this FlagValues object.
650
+
651
+ All unparsed arguments are returned.
652
+
653
+ Args:
654
+ argv: a tuple/list of strings.
655
+ known_only: bool, if True, parse and remove known flags; return the rest
656
+ untouched. Unknown flags specified by --undefok are not returned.
657
+
658
+ Returns:
659
+ The list of arguments not parsed as options, including argv[0].
660
+
661
+ Raises:
662
+ Error: Raised on any parsing error.
663
+ TypeError: Raised on passing wrong type of arguments.
664
+ ValueError: Raised on flag value parsing error.
665
+ """
666
+ if isinstance(argv, (str, bytes)):
667
+ raise TypeError(
668
+ 'argv should be a tuple/list of strings, not bytes or string.')
669
+ if not argv:
670
+ raise ValueError(
671
+ 'argv cannot be an empty list, and must contain the program name as '
672
+ 'the first element.')
673
+
674
+ # This pre parses the argv list for --flagfile=<> options.
675
+ program_name = argv[0]
676
+ args = self.read_flags_from_files(argv[1:], force_gnu=False)
677
+
678
+ # Parse the arguments.
679
+ unknown_flags, unparsed_args = self._parse_args(args, known_only)
680
+
681
+ # Handle unknown flags by raising UnrecognizedFlagError.
682
+ # Note some users depend on us raising this particular error.
683
+ for name, value in unknown_flags:
684
+ suggestions = _helpers.get_flag_suggestions(name, list(self))
685
+ raise _exceptions.UnrecognizedFlagError(
686
+ name, value, suggestions=suggestions)
687
+
688
+ self.mark_as_parsed()
689
+ self.validate_all_flags()
690
+ return [program_name] + unparsed_args
691
+
692
+ def __getstate__(self) -> Any:
693
+ raise TypeError("can't pickle FlagValues")
694
+
695
+ def __copy__(self) -> Any:
696
+ raise TypeError('FlagValues does not support shallow copies. '
697
+ 'Use absl.testing.flagsaver or copy.deepcopy instead.')
698
+
699
+ def __deepcopy__(self, memo) -> Any:
700
+ result = object.__new__(type(self))
701
+ result.__dict__.update(copy.deepcopy(self.__dict__, memo))
702
+ return result
703
+
704
+ def _set_is_retired_flag_func(self, is_retired_flag_func):
705
+ """Sets a function for checking retired flags.
706
+
707
+ Do not use it. This is a private absl API used to check retired flags
708
+ registered by the absl C++ flags library.
709
+
710
+ Args:
711
+ is_retired_flag_func: Callable(str) -> (bool, bool), a function takes flag
712
+ name as parameter, returns a tuple (is_retired, type_is_bool).
713
+ """
714
+ self.__dict__['__is_retired_flag_func'] = is_retired_flag_func
715
+
716
+ def _parse_args(
717
+ self, args: List[str], known_only: bool
718
+ ) -> Tuple[List[Tuple[Optional[str], Any]], List[str]]:
719
+ """Helper function to do the main argument parsing.
720
+
721
+ This function goes through args and does the bulk of the flag parsing.
722
+ It will find the corresponding flag in our flag dictionary, and call its
723
+ .parse() method on the flag value.
724
+
725
+ Args:
726
+ args: [str], a list of strings with the arguments to parse.
727
+ known_only: bool, if True, parse and remove known flags; return the rest
728
+ untouched. Unknown flags specified by --undefok are not returned.
729
+
730
+ Returns:
731
+ A tuple with the following:
732
+ unknown_flags: List of (flag name, arg) for flags we don't know about.
733
+ unparsed_args: List of arguments we did not parse.
734
+
735
+ Raises:
736
+ Error: Raised on any parsing error.
737
+ ValueError: Raised on flag value parsing error.
738
+ """
739
+ unparsed_names_and_args = [] # A list of (flag name or None, arg).
740
+ undefok = set()
741
+ retired_flag_func = self.__dict__['__is_retired_flag_func']
742
+
743
+ flag_dict = self._flags()
744
+ args = iter(args)
745
+ for arg in args:
746
+ value = None
747
+
748
+ def get_value():
749
+ # pylint: disable=cell-var-from-loop
750
+ try:
751
+ return next(args) if value is None else value
752
+ except StopIteration:
753
+ raise _exceptions.Error('Missing value for flag ' + arg) # pylint: disable=undefined-loop-variable
754
+
755
+ if not arg.startswith('-'):
756
+ # A non-argument: default is break, GNU is skip.
757
+ unparsed_names_and_args.append((None, arg))
758
+ if self.is_gnu_getopt():
759
+ continue
760
+ else:
761
+ break
762
+
763
+ if arg == '--':
764
+ if known_only:
765
+ unparsed_names_and_args.append((None, arg))
766
+ break
767
+
768
+ # At this point, arg must start with '-'.
769
+ if arg.startswith('--'):
770
+ arg_without_dashes = arg[2:]
771
+ else:
772
+ arg_without_dashes = arg[1:]
773
+
774
+ if '=' in arg_without_dashes:
775
+ name, value = arg_without_dashes.split('=', 1)
776
+ else:
777
+ name, value = arg_without_dashes, None
778
+
779
+ if not name:
780
+ # The argument is all dashes (including one dash).
781
+ unparsed_names_and_args.append((None, arg))
782
+ if self.is_gnu_getopt():
783
+ continue
784
+ else:
785
+ break
786
+
787
+ # --undefok is a special case.
788
+ if name == 'undefok':
789
+ value = get_value()
790
+ undefok.update(v.strip() for v in value.split(','))
791
+ undefok.update('no' + v.strip() for v in value.split(','))
792
+ continue
793
+
794
+ flag = flag_dict.get(name)
795
+ if flag is not None:
796
+ if flag.boolean and value is None:
797
+ value = 'true'
798
+ else:
799
+ value = get_value()
800
+ elif name.startswith('no') and len(name) > 2:
801
+ # Boolean flags can take the form of --noflag, with no value.
802
+ noflag = flag_dict.get(name[2:])
803
+ if noflag is not None and noflag.boolean:
804
+ if value is not None:
805
+ raise ValueError(arg + ' does not take an argument')
806
+ flag = noflag
807
+ value = 'false'
808
+
809
+ if retired_flag_func and flag is None:
810
+ is_retired, is_bool = retired_flag_func(name)
811
+
812
+ # If we didn't recognize that flag, but it starts with
813
+ # "no" then maybe it was a boolean flag specified in the
814
+ # --nofoo form.
815
+ if not is_retired and name.startswith('no'):
816
+ is_retired, is_bool = retired_flag_func(name[2:])
817
+ is_retired = is_retired and is_bool
818
+
819
+ if is_retired:
820
+ if not is_bool and value is None:
821
+ # This happens when a non-bool retired flag is specified
822
+ # in format of "--flag value".
823
+ get_value()
824
+ logging.error(
825
+ 'Flag "%s" is retired and should no longer be specified. See '
826
+ 'https://abseil.io/tips/90.',
827
+ name,
828
+ )
829
+ continue
830
+
831
+ if flag is not None:
832
+ # LINT.IfChange
833
+ flag.parse(value)
834
+ flag.using_default_value = False
835
+ # LINT.ThenChange(../testing/flagsaver.py:flag_override_parsing)
836
+ else:
837
+ unparsed_names_and_args.append((name, arg))
838
+
839
+ unknown_flags = []
840
+ unparsed_args = []
841
+ for name, arg in unparsed_names_and_args:
842
+ if name is None:
843
+ # Positional arguments.
844
+ unparsed_args.append(arg)
845
+ elif name in undefok:
846
+ # Remove undefok flags.
847
+ continue
848
+ else:
849
+ # This is an unknown flag.
850
+ if known_only:
851
+ unparsed_args.append(arg)
852
+ else:
853
+ unknown_flags.append((name, arg))
854
+
855
+ unparsed_args.extend(list(args))
856
+ return unknown_flags, unparsed_args
857
+
858
+ def is_parsed(self) -> bool:
859
+ """Returns whether flags were parsed."""
860
+ return self.__dict__['__flags_parsed']
861
+
862
+ def mark_as_parsed(self) -> None:
863
+ """Explicitly marks flags as parsed.
864
+
865
+ Use this when the caller knows that this FlagValues has been parsed as if
866
+ a ``__call__()`` invocation has happened. This is only a public method for
867
+ use by things like appcommands which do additional command like parsing.
868
+ """
869
+ self.__dict__['__flags_parsed'] = True
870
+
871
+ def unparse_flags(self) -> None:
872
+ """Unparses all flags to the point before any FLAGS(argv) was called."""
873
+ for f in self._flags().values():
874
+ f.unparse()
875
+ # We log this message before marking flags as unparsed to avoid a
876
+ # problem when the logging library causes flags access.
877
+ logging.info('unparse_flags() called; flags access will now raise errors.')
878
+ self.__dict__['__flags_parsed'] = False
879
+ self.__dict__['__unparse_flags_called'] = True
880
+
881
+ def flag_values_dict(self) -> Dict[Text, Any]:
882
+ """Returns a dictionary that maps flag names to flag values."""
883
+ return {name: flag.value for name, flag in self._flags().items()}
884
+
885
+ def __str__(self):
886
+ """Returns a help string for all known flags."""
887
+ return self.get_help()
888
+
889
+ def get_help(
890
+ self, prefix: Text = '', include_special_flags: bool = True
891
+ ) -> Text:
892
+ """Returns a help string for all known flags.
893
+
894
+ Args:
895
+ prefix: str, per-line output prefix.
896
+ include_special_flags: bool, whether to include description of
897
+ SPECIAL_FLAGS, i.e. --flagfile and --undefok.
898
+
899
+ Returns:
900
+ str, formatted help message.
901
+ """
902
+ flags_by_module = self.flags_by_module_dict()
903
+ if flags_by_module:
904
+ modules = sorted(flags_by_module)
905
+ # Print the help for the main module first, if possible.
906
+ main_module = sys.argv[0]
907
+ if main_module in modules:
908
+ modules.remove(main_module)
909
+ modules = [main_module] + modules
910
+ return self._get_help_for_modules(modules, prefix, include_special_flags)
911
+ else:
912
+ output_lines = []
913
+ # Just print one long list of flags.
914
+ values = self._flags().values()
915
+ if include_special_flags:
916
+ values = itertools.chain(
917
+ values, _helpers.SPECIAL_FLAGS._flags().values() # pylint: disable=protected-access # pytype: disable=attribute-error
918
+ )
919
+ self._render_flag_list(values, output_lines, prefix)
920
+ return '\n'.join(output_lines)
921
+
922
+ def _get_help_for_modules(self, modules, prefix, include_special_flags):
923
+ """Returns the help string for a list of modules.
924
+
925
+ Private to absl.flags package.
926
+
927
+ Args:
928
+ modules: List[str], a list of modules to get the help string for.
929
+ prefix: str, a string that is prepended to each generated help line.
930
+ include_special_flags: bool, whether to include description of
931
+ SPECIAL_FLAGS, i.e. --flagfile and --undefok.
932
+ """
933
+ output_lines = []
934
+ for module in modules:
935
+ self._render_our_module_flags(module, output_lines, prefix)
936
+ if include_special_flags:
937
+ self._render_module_flags(
938
+ 'absl.flags',
939
+ _helpers.SPECIAL_FLAGS._flags().values(), # pylint: disable=protected-access # pytype: disable=attribute-error
940
+ output_lines,
941
+ prefix,
942
+ )
943
+ return '\n'.join(output_lines)
944
+
945
+ def _render_module_flags(self, module, flags, output_lines, prefix=''):
946
+ """Returns a help string for a given module."""
947
+ if not isinstance(module, str):
948
+ module = module.__name__
949
+ output_lines.append('\n%s%s:' % (prefix, module))
950
+ self._render_flag_list(flags, output_lines, prefix + ' ')
951
+
952
+ def _render_our_module_flags(self, module, output_lines, prefix=''):
953
+ """Returns a help string for a given module."""
954
+ flags = self.get_flags_for_module(module)
955
+ if flags:
956
+ self._render_module_flags(module, flags, output_lines, prefix)
957
+
958
+ def _render_our_module_key_flags(self, module, output_lines, prefix=''):
959
+ """Returns a help string for the key flags of a given module.
960
+
961
+ Args:
962
+ module: module|str, the module to render key flags for.
963
+ output_lines: [str], a list of strings. The generated help message lines
964
+ will be appended to this list.
965
+ prefix: str, a string that is prepended to each generated help line.
966
+ """
967
+ key_flags = self.get_key_flags_for_module(module)
968
+ if key_flags:
969
+ self._render_module_flags(module, key_flags, output_lines, prefix)
970
+
971
+ def module_help(self, module: Any) -> Text:
972
+ """Describes the key flags of a module.
973
+
974
+ Args:
975
+ module: module|str, the module to describe the key flags for.
976
+
977
+ Returns:
978
+ str, describing the key flags of a module.
979
+ """
980
+ helplist = []
981
+ self._render_our_module_key_flags(module, helplist)
982
+ return '\n'.join(helplist)
983
+
984
+ def main_module_help(self) -> Text:
985
+ """Describes the key flags of the main module.
986
+
987
+ Returns:
988
+ str, describing the key flags of the main module.
989
+ """
990
+ return self.module_help(sys.argv[0])
991
+
992
+ def _render_flag_list(self, flaglist, output_lines, prefix=' '):
993
+ fl = self._flags()
994
+ special_fl = _helpers.SPECIAL_FLAGS._flags() # pylint: disable=protected-access # pytype: disable=attribute-error
995
+ flaglist = [(flag.name, flag) for flag in flaglist]
996
+ flaglist.sort()
997
+ flagset = {}
998
+ for (name, flag) in flaglist:
999
+ # It's possible this flag got deleted or overridden since being
1000
+ # registered in the per-module flaglist. Check now against the
1001
+ # canonical source of current flag information, the _flags.
1002
+ if fl.get(name, None) != flag and special_fl.get(name, None) != flag:
1003
+ # a different flag is using this name now
1004
+ continue
1005
+ # only print help once
1006
+ if flag in flagset:
1007
+ continue
1008
+ flagset[flag] = 1
1009
+ flaghelp = ''
1010
+ if flag.short_name:
1011
+ flaghelp += '-%s,' % flag.short_name
1012
+ if flag.boolean:
1013
+ flaghelp += '--[no]%s:' % flag.name
1014
+ else:
1015
+ flaghelp += '--%s:' % flag.name
1016
+ flaghelp += ' '
1017
+ if flag.help:
1018
+ flaghelp += flag.help
1019
+ flaghelp = _helpers.text_wrap(
1020
+ flaghelp, indent=prefix + ' ', firstline_indent=prefix)
1021
+ if flag.default_as_str:
1022
+ flaghelp += '\n'
1023
+ flaghelp += _helpers.text_wrap(
1024
+ '(default: %s)' % flag.default_as_str, indent=prefix + ' ')
1025
+ if flag.parser.syntactic_help:
1026
+ flaghelp += '\n'
1027
+ flaghelp += _helpers.text_wrap(
1028
+ '(%s)' % flag.parser.syntactic_help, indent=prefix + ' ')
1029
+ output_lines.append(flaghelp)
1030
+
1031
+ def get_flag_value(self, name: Text, default: Any) -> Any: # pylint: disable=invalid-name
1032
+ """Returns the value of a flag (if not None) or a default value.
1033
+
1034
+ Args:
1035
+ name: str, the name of a flag.
1036
+ default: Default value to use if the flag value is None.
1037
+
1038
+ Returns:
1039
+ Requested flag value or default.
1040
+ """
1041
+
1042
+ value = self.__getattr__(name)
1043
+ if value is not None: # Can't do if not value, b/c value might be '0' or ""
1044
+ return value
1045
+ else:
1046
+ return default
1047
+
1048
+ def _is_flag_file_directive(self, flag_string):
1049
+ """Checks whether flag_string contain a --flagfile=<foo> directive."""
1050
+ if isinstance(flag_string, str):
1051
+ if flag_string.startswith('--flagfile='):
1052
+ return 1
1053
+ elif flag_string == '--flagfile':
1054
+ return 1
1055
+ elif flag_string.startswith('-flagfile='):
1056
+ return 1
1057
+ elif flag_string == '-flagfile':
1058
+ return 1
1059
+ else:
1060
+ return 0
1061
+ return 0
1062
+
1063
+ def _extract_filename(self, flagfile_str):
1064
+ """Returns filename from a flagfile_str of form -[-]flagfile=filename.
1065
+
1066
+ The cases of --flagfile foo and -flagfile foo shouldn't be hitting
1067
+ this function, as they are dealt with in the level above this
1068
+ function.
1069
+
1070
+ Args:
1071
+ flagfile_str: str, the flagfile string.
1072
+
1073
+ Returns:
1074
+ str, the filename from a flagfile_str of form -[-]flagfile=filename.
1075
+
1076
+ Raises:
1077
+ Error: Raised when illegal --flagfile is provided.
1078
+ """
1079
+ if flagfile_str.startswith('--flagfile='):
1080
+ return os.path.expanduser((flagfile_str[(len('--flagfile=')):]).strip())
1081
+ elif flagfile_str.startswith('-flagfile='):
1082
+ return os.path.expanduser((flagfile_str[(len('-flagfile=')):]).strip())
1083
+ else:
1084
+ raise _exceptions.Error('Hit illegal --flagfile type: %s' % flagfile_str)
1085
+
1086
+ def _get_flag_file_lines(self, filename, parsed_file_stack=None):
1087
+ """Returns the useful (!=comments, etc) lines from a file with flags.
1088
+
1089
+ Args:
1090
+ filename: str, the name of the flag file.
1091
+ parsed_file_stack: [str], a list of the names of the files that we have
1092
+ recursively encountered at the current depth. MUTATED BY THIS FUNCTION
1093
+ (but the original value is preserved upon successfully returning from
1094
+ function call).
1095
+
1096
+ Returns:
1097
+ List of strings. See the note below.
1098
+
1099
+ NOTE(springer): This function checks for a nested --flagfile=<foo>
1100
+ tag and handles the lower file recursively. It returns a list of
1101
+ all the lines that _could_ contain command flags. This is
1102
+ EVERYTHING except whitespace lines and comments (lines starting
1103
+ with '#' or '//').
1104
+ """
1105
+ # For consistency with the cpp version, ignore empty values.
1106
+ if not filename:
1107
+ return []
1108
+ if parsed_file_stack is None:
1109
+ parsed_file_stack = []
1110
+ # We do a little safety check for reparsing a file we've already encountered
1111
+ # at a previous depth.
1112
+ if filename in parsed_file_stack:
1113
+ sys.stderr.write('Warning: Hit circular flagfile dependency. Ignoring'
1114
+ ' flagfile: %s\n' % (filename,))
1115
+ return []
1116
+ else:
1117
+ parsed_file_stack.append(filename)
1118
+
1119
+ line_list = [] # All line from flagfile.
1120
+ flag_line_list = [] # Subset of lines w/o comments, blanks, flagfile= tags.
1121
+ try:
1122
+ file_obj = open(filename, 'r')
1123
+ except IOError as e_msg:
1124
+ raise _exceptions.CantOpenFlagFileError(
1125
+ 'ERROR:: Unable to open flagfile: %s' % e_msg)
1126
+
1127
+ with file_obj:
1128
+ line_list = file_obj.readlines()
1129
+
1130
+ # This is where we check each line in the file we just read.
1131
+ for line in line_list:
1132
+ if line.isspace():
1133
+ pass
1134
+ # Checks for comment (a line that starts with '#').
1135
+ elif line.startswith('#') or line.startswith('//'):
1136
+ pass
1137
+ # Checks for a nested "--flagfile=<bar>" flag in the current file.
1138
+ # If we find one, recursively parse down into that file.
1139
+ elif self._is_flag_file_directive(line):
1140
+ sub_filename = self._extract_filename(line)
1141
+ included_flags = self._get_flag_file_lines(
1142
+ sub_filename, parsed_file_stack=parsed_file_stack)
1143
+ flag_line_list.extend(included_flags)
1144
+ else:
1145
+ # Any line that's not a comment or a nested flagfile should get
1146
+ # copied into 2nd position. This leaves earlier arguments
1147
+ # further back in the list, thus giving them higher priority.
1148
+ flag_line_list.append(line.strip())
1149
+
1150
+ parsed_file_stack.pop()
1151
+ return flag_line_list
1152
+
1153
+ def read_flags_from_files(
1154
+ self, argv: Sequence[Text], force_gnu: bool = True
1155
+ ) -> List[Text]:
1156
+ """Processes command line args, but also allow args to be read from file.
1157
+
1158
+ Args:
1159
+ argv: [str], a list of strings, usually sys.argv[1:], which may contain
1160
+ one or more flagfile directives of the form --flagfile="./filename".
1161
+ Note that the name of the program (sys.argv[0]) should be omitted.
1162
+ force_gnu: bool, if False, --flagfile parsing obeys the
1163
+ FLAGS.is_gnu_getopt() value. If True, ignore the value and always follow
1164
+ gnu_getopt semantics.
1165
+
1166
+ Returns:
1167
+ A new list which has the original list combined with what we read
1168
+ from any flagfile(s).
1169
+
1170
+ Raises:
1171
+ IllegalFlagValueError: Raised when --flagfile is provided with no
1172
+ argument.
1173
+
1174
+ This function is called by FLAGS(argv).
1175
+ It scans the input list for a flag that looks like:
1176
+ --flagfile=<somefile>. Then it opens <somefile>, reads all valid key
1177
+ and value pairs and inserts them into the input list in exactly the
1178
+ place where the --flagfile arg is found.
1179
+
1180
+ Note that your application's flags are still defined the usual way
1181
+ using absl.flags DEFINE_flag() type functions.
1182
+
1183
+ Notes (assuming we're getting a commandline of some sort as our input):
1184
+
1185
+ * For duplicate flags, the last one we hit should "win".
1186
+ * Since flags that appear later win, a flagfile's settings can be "weak"
1187
+ if the --flagfile comes at the beginning of the argument sequence,
1188
+ and it can be "strong" if the --flagfile comes at the end.
1189
+ * A further "--flagfile=<otherfile.cfg>" CAN be nested in a flagfile.
1190
+ It will be expanded in exactly the spot where it is found.
1191
+ * In a flagfile, a line beginning with # or // is a comment.
1192
+ * Entirely blank lines _should_ be ignored.
1193
+ """
1194
+ rest_of_args = argv
1195
+ new_argv = []
1196
+ while rest_of_args:
1197
+ current_arg = rest_of_args[0]
1198
+ rest_of_args = rest_of_args[1:]
1199
+ if self._is_flag_file_directive(current_arg):
1200
+ # This handles the case of -(-)flagfile foo. In this case the
1201
+ # next arg really is part of this one.
1202
+ if current_arg == '--flagfile' or current_arg == '-flagfile':
1203
+ if not rest_of_args:
1204
+ raise _exceptions.IllegalFlagValueError(
1205
+ '--flagfile with no argument')
1206
+ flag_filename = os.path.expanduser(rest_of_args[0])
1207
+ rest_of_args = rest_of_args[1:]
1208
+ else:
1209
+ # This handles the case of (-)-flagfile=foo.
1210
+ flag_filename = self._extract_filename(current_arg)
1211
+ new_argv.extend(self._get_flag_file_lines(flag_filename))
1212
+ else:
1213
+ new_argv.append(current_arg)
1214
+ # Stop parsing after '--', like getopt and gnu_getopt.
1215
+ if current_arg == '--':
1216
+ break
1217
+ # Stop parsing after a non-flag, like getopt.
1218
+ if not current_arg.startswith('-'):
1219
+ if not force_gnu and not self.__dict__['__use_gnu_getopt']:
1220
+ break
1221
+ else:
1222
+ if ('=' not in current_arg and rest_of_args and
1223
+ not rest_of_args[0].startswith('-')):
1224
+ # If this is an occurrence of a legitimate --x y, skip the value
1225
+ # so that it won't be mistaken for a standalone arg.
1226
+ fl = self._flags()
1227
+ name = current_arg.lstrip('-')
1228
+ if name in fl and not fl[name].boolean:
1229
+ current_arg = rest_of_args[0]
1230
+ rest_of_args = rest_of_args[1:]
1231
+ new_argv.append(current_arg)
1232
+
1233
+ if rest_of_args:
1234
+ new_argv.extend(rest_of_args)
1235
+
1236
+ return new_argv
1237
+
1238
+ def flags_into_string(self) -> Text:
1239
+ """Returns a string with the flags assignments from this FlagValues object.
1240
+
1241
+ This function ignores flags whose value is None. Each flag
1242
+ assignment is separated by a newline.
1243
+
1244
+ NOTE: MUST mirror the behavior of the C++ CommandlineFlagsIntoString
1245
+ from https://github.com/gflags/gflags.
1246
+
1247
+ Returns:
1248
+ str, the string with the flags assignments from this FlagValues object.
1249
+ The flags are ordered by (module_name, flag_name).
1250
+ """
1251
+ module_flags = sorted(self.flags_by_module_dict().items())
1252
+ s = ''
1253
+ for unused_module_name, flags in module_flags:
1254
+ flags = sorted(flags, key=lambda f: f.name)
1255
+ for flag in flags:
1256
+ if flag.value is not None:
1257
+ s += flag.serialize() + '\n'
1258
+ return s
1259
+
1260
+ def append_flags_into_file(self, filename: Text) -> None:
1261
+ """Appends all flags assignments from this FlagInfo object to a file.
1262
+
1263
+ Output will be in the format of a flagfile.
1264
+
1265
+ NOTE: MUST mirror the behavior of the C++ AppendFlagsIntoFile
1266
+ from https://github.com/gflags/gflags.
1267
+
1268
+ Args:
1269
+ filename: str, name of the file.
1270
+ """
1271
+ with open(filename, 'a') as out_file:
1272
+ out_file.write(self.flags_into_string())
1273
+
1274
+ def write_help_in_xml_format(self, outfile: Optional[TextIO] = None) -> None:
1275
+ """Outputs flag documentation in XML format.
1276
+
1277
+ NOTE: We use element names that are consistent with those used by
1278
+ the C++ command-line flag library, from
1279
+ https://github.com/gflags/gflags.
1280
+ We also use a few new elements (e.g., <key>), but we do not
1281
+ interfere / overlap with existing XML elements used by the C++
1282
+ library. Please maintain this consistency.
1283
+
1284
+ Args:
1285
+ outfile: File object we write to. Default None means sys.stdout.
1286
+ """
1287
+ doc = minidom.Document()
1288
+ all_flag = doc.createElement('AllFlags')
1289
+ doc.appendChild(all_flag)
1290
+
1291
+ all_flag.appendChild(
1292
+ _helpers.create_xml_dom_element(doc, 'program',
1293
+ os.path.basename(sys.argv[0])))
1294
+
1295
+ usage_doc = sys.modules['__main__'].__doc__
1296
+ if not usage_doc:
1297
+ usage_doc = '\nUSAGE: %s [flags]\n' % sys.argv[0]
1298
+ else:
1299
+ usage_doc = usage_doc.replace('%s', sys.argv[0])
1300
+ all_flag.appendChild(
1301
+ _helpers.create_xml_dom_element(doc, 'usage', usage_doc))
1302
+
1303
+ # Get list of key flags for the main module.
1304
+ key_flags = self.get_key_flags_for_module(sys.argv[0])
1305
+
1306
+ # Sort flags by declaring module name and next by flag name.
1307
+ flags_by_module = self.flags_by_module_dict()
1308
+ all_module_names = list(flags_by_module.keys())
1309
+ all_module_names.sort()
1310
+ for module_name in all_module_names:
1311
+ flag_list = [(f.name, f) for f in flags_by_module[module_name]]
1312
+ flag_list.sort()
1313
+ for unused_flag_name, flag in flag_list:
1314
+ is_key = flag in key_flags
1315
+ all_flag.appendChild(
1316
+ flag._create_xml_dom_element( # pylint: disable=protected-access
1317
+ doc,
1318
+ module_name,
1319
+ is_key=is_key))
1320
+
1321
+ outfile = outfile or sys.stdout
1322
+ outfile.write(
1323
+ doc.toprettyxml(indent=' ', encoding='utf-8').decode('utf-8'))
1324
+ outfile.flush()
1325
+
1326
+ def _check_method_name_conflicts(self, name: str, flag: Flag):
1327
+ if flag.allow_using_method_names:
1328
+ return
1329
+ short_name = flag.short_name
1330
+ flag_names = {name} if short_name is None else {name, short_name}
1331
+ for flag_name in flag_names:
1332
+ if flag_name in self.__dict__['__banned_flag_names']:
1333
+ raise _exceptions.FlagNameConflictsWithMethodError(
1334
+ 'Cannot define a flag named "{name}". It conflicts with a method '
1335
+ 'on class "{class_name}". To allow defining it, use '
1336
+ 'allow_using_method_names and access the flag value with '
1337
+ "FLAGS['{name}'].value. FLAGS.{name} returns the method, "
1338
+ 'not the flag value.'.format(
1339
+ name=flag_name, class_name=type(self).__name__))
1340
+
1341
+
1342
+ FLAGS = FlagValues()
1343
+
1344
+
1345
+ class FlagHolder(Generic[_T]):
1346
+ """Holds a defined flag.
1347
+
1348
+ This facilitates a cleaner api around global state. Instead of::
1349
+
1350
+ flags.DEFINE_integer('foo', ...)
1351
+ flags.DEFINE_integer('bar', ...)
1352
+
1353
+ def method():
1354
+ # prints parsed value of 'bar' flag
1355
+ print(flags.FLAGS.foo)
1356
+ # runtime error due to typo or possibly bad coding style.
1357
+ print(flags.FLAGS.baz)
1358
+
1359
+ it encourages code like::
1360
+
1361
+ _FOO_FLAG = flags.DEFINE_integer('foo', ...)
1362
+ _BAR_FLAG = flags.DEFINE_integer('bar', ...)
1363
+
1364
+ def method():
1365
+ print(_FOO_FLAG.value)
1366
+ print(_BAR_FLAG.value)
1367
+
1368
+ since the name of the flag appears only once in the source code.
1369
+ """
1370
+
1371
+ value: _T
1372
+
1373
+ def __init__(
1374
+ self,
1375
+ flag_values: FlagValues,
1376
+ flag: Flag[_T],
1377
+ ensure_non_none_value: bool = False,
1378
+ ):
1379
+ """Constructs a FlagHolder instance providing typesafe access to flag.
1380
+
1381
+ Args:
1382
+ flag_values: The container the flag is registered to.
1383
+ flag: The flag object for this flag.
1384
+ ensure_non_none_value: Is the value of the flag allowed to be None.
1385
+ """
1386
+ self._flagvalues = flag_values
1387
+ # We take the entire flag object, but only keep the name. Why?
1388
+ # - We want FlagHolder[T] to be generic container
1389
+ # - flag_values contains all flags, so has no reference to T.
1390
+ # - typecheckers don't like to see a generic class where none of the ctor
1391
+ # arguments refer to the generic type.
1392
+ self._name = flag.name
1393
+ # We intentionally do NOT check if the default value is None.
1394
+ # This allows future use of this for "required flags with None default"
1395
+ self._ensure_non_none_value = ensure_non_none_value
1396
+
1397
+ def __eq__(self, other):
1398
+ raise TypeError(
1399
+ "unsupported operand type(s) for ==: '{0}' and '{1}' "
1400
+ "(did you mean to use '{0}.value' instead?)".format(
1401
+ type(self).__name__, type(other).__name__))
1402
+
1403
+ def __bool__(self):
1404
+ raise TypeError(
1405
+ "bool() not supported for instances of type '{0}' "
1406
+ "(did you mean to use '{0}.value' instead?)".format(
1407
+ type(self).__name__))
1408
+
1409
+ __nonzero__ = __bool__
1410
+
1411
+ @property
1412
+ def name(self) -> Text:
1413
+ return self._name
1414
+
1415
+ @property
1416
+ def value(self) -> _T:
1417
+ """Returns the value of the flag.
1418
+
1419
+ If ``_ensure_non_none_value`` is ``True``, then return value is not
1420
+ ``None``.
1421
+
1422
+ Raises:
1423
+ UnparsedFlagAccessError: if flag parsing has not finished.
1424
+ IllegalFlagValueError: if value is None unexpectedly.
1425
+ """
1426
+ val = getattr(self._flagvalues, self._name)
1427
+ if self._ensure_non_none_value and val is None:
1428
+ raise _exceptions.IllegalFlagValueError(
1429
+ 'Unexpected None value for flag %s' % self._name)
1430
+ return val
1431
+
1432
+ @property
1433
+ def default(self) -> _T:
1434
+ """Returns the default value of the flag."""
1435
+ return self._flagvalues[self._name].default
1436
+
1437
+ @property
1438
+ def present(self) -> bool:
1439
+ """Returns True if the flag was parsed from command-line flags."""
1440
+ return bool(self._flagvalues[self._name].present)
1441
+
1442
+ def serialize(self) -> Text:
1443
+ """Returns a serialized representation of the flag."""
1444
+ return self._flagvalues[self._name].serialize()
1445
+
1446
+
1447
+ def resolve_flag_ref(
1448
+ flag_ref: Union[str, FlagHolder], flag_values: FlagValues
1449
+ ) -> Tuple[str, FlagValues]:
1450
+ """Helper to validate and resolve a flag reference argument."""
1451
+ if isinstance(flag_ref, FlagHolder):
1452
+ new_flag_values = flag_ref._flagvalues # pylint: disable=protected-access
1453
+ if flag_values != FLAGS and flag_values != new_flag_values:
1454
+ raise ValueError(
1455
+ 'flag_values must not be customized when operating on a FlagHolder')
1456
+ return flag_ref.name, new_flag_values
1457
+ return flag_ref, flag_values
1458
+
1459
+
1460
+ def resolve_flag_refs(
1461
+ flag_refs: Sequence[Union[str, FlagHolder]], flag_values: FlagValues
1462
+ ) -> Tuple[List[str], FlagValues]:
1463
+ """Helper to validate and resolve flag reference list arguments."""
1464
+ fv = None
1465
+ names = []
1466
+ for ref in flag_refs:
1467
+ if isinstance(ref, FlagHolder):
1468
+ newfv = ref._flagvalues # pylint: disable=protected-access
1469
+ name = ref.name
1470
+ else:
1471
+ newfv = flag_values
1472
+ name = ref
1473
+ if fv and fv != newfv:
1474
+ raise ValueError(
1475
+ 'multiple FlagValues instances used in invocation. '
1476
+ 'FlagHolders must be registered to the same FlagValues instance as '
1477
+ 'do flag names, if provided.')
1478
+ fv = newfv
1479
+ names.append(name)
1480
+ return names, fv
MLPY/Lib/site-packages/absl/flags/_helpers.py ADDED
@@ -0,0 +1,421 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2017 The Abseil Authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Internal helper functions for Abseil Python flags library."""
16
+
17
+ import os
18
+ import re
19
+ import struct
20
+ import sys
21
+ import textwrap
22
+ import types
23
+ from typing import Any, Dict, Iterable, List, NamedTuple, Optional, Sequence, Set
24
+ from xml.dom import minidom
25
+ # pylint: disable=g-import-not-at-top
26
+ try:
27
+ import fcntl
28
+ except ImportError:
29
+ fcntl = None
30
+ try:
31
+ # Importing termios will fail on non-unix platforms.
32
+ import termios
33
+ except ImportError:
34
+ termios = None
35
+ # pylint: enable=g-import-not-at-top
36
+
37
+
38
+ _DEFAULT_HELP_WIDTH = 80 # Default width of help output.
39
+ # Minimal "sane" width of help output. We assume that any value below 40 is
40
+ # unreasonable.
41
+ _MIN_HELP_WIDTH = 40
42
+
43
+ # Define the allowed error rate in an input string to get suggestions.
44
+ #
45
+ # We lean towards a high threshold because we tend to be matching a phrase,
46
+ # and the simple algorithm used here is geared towards correcting word
47
+ # spellings.
48
+ #
49
+ # For manual testing, consider "<command> --list" which produced a large number
50
+ # of spurious suggestions when we used "least_errors > 0.5" instead of
51
+ # "least_erros >= 0.5".
52
+ _SUGGESTION_ERROR_RATE_THRESHOLD = 0.50
53
+
54
+ # Characters that cannot appear or are highly discouraged in an XML 1.0
55
+ # document. (See http://www.w3.org/TR/REC-xml/#charsets or
56
+ # https://en.wikipedia.org/wiki/Valid_characters_in_XML#XML_1.0)
57
+ _ILLEGAL_XML_CHARS_REGEX = re.compile(
58
+ u'[\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]')
59
+
60
+ # This is a set of module ids for the modules that disclaim key flags.
61
+ # This module is explicitly added to this set so that we never consider it to
62
+ # define key flag.
63
+ disclaim_module_ids: Set[int] = set([id(sys.modules[__name__])])
64
+
65
+
66
+ # Define special flags here so that help may be generated for them.
67
+ # NOTE: Please do NOT use SPECIAL_FLAGS from outside flags module.
68
+ # Initialized inside flagvalues.py.
69
+ # NOTE: This cannot be annotated as its actual FlagValues type since this would
70
+ # create a circular dependency.
71
+ SPECIAL_FLAGS: Any = None
72
+
73
+
74
+ # This points to the flags module, initialized in flags/__init__.py.
75
+ # This should only be used in adopt_module_key_flags to take SPECIAL_FLAGS into
76
+ # account.
77
+ FLAGS_MODULE: types.ModuleType = None
78
+
79
+
80
+ class _ModuleObjectAndName(NamedTuple):
81
+ """Module object and name.
82
+
83
+ Fields:
84
+ - module: object, module object.
85
+ - module_name: str, module name.
86
+ """
87
+ module: types.ModuleType
88
+ module_name: str
89
+
90
+
91
+ def get_module_object_and_name(
92
+ globals_dict: Dict[str, Any]
93
+ ) -> _ModuleObjectAndName:
94
+ """Returns the module that defines a global environment, and its name.
95
+
96
+ Args:
97
+ globals_dict: A dictionary that should correspond to an environment
98
+ providing the values of the globals.
99
+
100
+ Returns:
101
+ _ModuleObjectAndName - pair of module object & module name.
102
+ Returns (None, None) if the module could not be identified.
103
+ """
104
+ name = globals_dict.get('__name__', None)
105
+ module = sys.modules.get(name, None)
106
+ # Pick a more informative name for the main module.
107
+ return _ModuleObjectAndName(module,
108
+ (sys.argv[0] if name == '__main__' else name))
109
+
110
+
111
+ def get_calling_module_object_and_name() -> _ModuleObjectAndName:
112
+ """Returns the module that's calling into this module.
113
+
114
+ We generally use this function to get the name of the module calling a
115
+ DEFINE_foo... function.
116
+
117
+ Returns:
118
+ The module object that called into this one.
119
+
120
+ Raises:
121
+ AssertionError: Raised when no calling module could be identified.
122
+ """
123
+ for depth in range(1, sys.getrecursionlimit()):
124
+ # sys._getframe is the right thing to use here, as it's the best
125
+ # way to walk up the call stack.
126
+ globals_for_frame = sys._getframe(depth).f_globals # pylint: disable=protected-access
127
+ module, module_name = get_module_object_and_name(globals_for_frame)
128
+ if id(module) not in disclaim_module_ids and module_name is not None:
129
+ return _ModuleObjectAndName(module, module_name)
130
+ raise AssertionError('No module was found')
131
+
132
+
133
+ def get_calling_module() -> str:
134
+ """Returns the name of the module that's calling into this module."""
135
+ return get_calling_module_object_and_name().module_name
136
+
137
+
138
+ def create_xml_dom_element(
139
+ doc: minidom.Document, name: str, value: Any
140
+ ) -> minidom.Element:
141
+ """Returns an XML DOM element with name and text value.
142
+
143
+ Args:
144
+ doc: minidom.Document, the DOM document it should create nodes from.
145
+ name: str, the tag of XML element.
146
+ value: object, whose string representation will be used
147
+ as the value of the XML element. Illegal or highly discouraged xml 1.0
148
+ characters are stripped.
149
+
150
+ Returns:
151
+ An instance of minidom.Element.
152
+ """
153
+ s = str(value)
154
+ if isinstance(value, bool):
155
+ # Display boolean values as the C++ flag library does: no caps.
156
+ s = s.lower()
157
+ # Remove illegal xml characters.
158
+ s = _ILLEGAL_XML_CHARS_REGEX.sub(u'', s)
159
+
160
+ e = doc.createElement(name)
161
+ e.appendChild(doc.createTextNode(s))
162
+ return e
163
+
164
+
165
+ def get_help_width() -> int:
166
+ """Returns the integer width of help lines that is used in TextWrap."""
167
+ if not sys.stdout.isatty() or termios is None or fcntl is None:
168
+ return _DEFAULT_HELP_WIDTH
169
+ try:
170
+ data = fcntl.ioctl(sys.stdout, termios.TIOCGWINSZ, b'1234')
171
+ columns = struct.unpack('hh', data)[1]
172
+ # Emacs mode returns 0.
173
+ # Here we assume that any value below 40 is unreasonable.
174
+ if columns >= _MIN_HELP_WIDTH:
175
+ return columns
176
+ # Returning an int as default is fine, int(int) just return the int.
177
+ return int(os.getenv('COLUMNS', _DEFAULT_HELP_WIDTH))
178
+
179
+ except (TypeError, IOError, struct.error):
180
+ return _DEFAULT_HELP_WIDTH
181
+
182
+
183
+ def get_flag_suggestions(
184
+ attempt: Optional[str], longopt_list: Sequence[str]
185
+ ) -> List[str]:
186
+ """Returns helpful similar matches for an invalid flag."""
187
+ # Don't suggest on very short strings, or if no longopts are specified.
188
+ if len(attempt) <= 2 or not longopt_list:
189
+ return []
190
+
191
+ option_names = [v.split('=')[0] for v in longopt_list]
192
+
193
+ # Find close approximations in flag prefixes.
194
+ # This also handles the case where the flag is spelled right but ambiguous.
195
+ distances = [(_damerau_levenshtein(attempt, option[0:len(attempt)]), option)
196
+ for option in option_names]
197
+ # t[0] is distance, and sorting by t[1] allows us to have stable output.
198
+ distances.sort()
199
+
200
+ least_errors, _ = distances[0]
201
+ # Don't suggest excessively bad matches.
202
+ if least_errors >= _SUGGESTION_ERROR_RATE_THRESHOLD * len(attempt):
203
+ return []
204
+
205
+ suggestions = []
206
+ for errors, name in distances:
207
+ if errors == least_errors:
208
+ suggestions.append(name)
209
+ else:
210
+ break
211
+ return suggestions
212
+
213
+
214
+ def _damerau_levenshtein(a, b):
215
+ """Returns Damerau-Levenshtein edit distance from a to b."""
216
+ memo = {}
217
+
218
+ def distance(x, y):
219
+ """Recursively defined string distance with memoization."""
220
+ if (x, y) in memo:
221
+ return memo[x, y]
222
+ if not x:
223
+ d = len(y)
224
+ elif not y:
225
+ d = len(x)
226
+ else:
227
+ d = min(
228
+ distance(x[1:], y) + 1, # correct an insertion error
229
+ distance(x, y[1:]) + 1, # correct a deletion error
230
+ distance(x[1:], y[1:]) + (x[0] != y[0])) # correct a wrong character
231
+ if len(x) >= 2 and len(y) >= 2 and x[0] == y[1] and x[1] == y[0]:
232
+ # Correct a transposition.
233
+ t = distance(x[2:], y[2:]) + 1
234
+ if d > t:
235
+ d = t
236
+
237
+ memo[x, y] = d
238
+ return d
239
+ return distance(a, b)
240
+
241
+
242
+ def text_wrap(
243
+ text: str,
244
+ length: Optional[int] = None,
245
+ indent: str = '',
246
+ firstline_indent: Optional[str] = None,
247
+ ) -> str:
248
+ """Wraps a given text to a maximum line length and returns it.
249
+
250
+ It turns lines that only contain whitespace into empty lines, keeps new lines,
251
+ and expands tabs using 4 spaces.
252
+
253
+ Args:
254
+ text: str, text to wrap.
255
+ length: int, maximum length of a line, includes indentation.
256
+ If this is None then use get_help_width()
257
+ indent: str, indent for all but first line.
258
+ firstline_indent: str, indent for first line; if None, fall back to indent.
259
+
260
+ Returns:
261
+ str, the wrapped text.
262
+
263
+ Raises:
264
+ ValueError: Raised if indent or firstline_indent not shorter than length.
265
+ """
266
+ # Get defaults where callee used None
267
+ if length is None:
268
+ length = get_help_width()
269
+ if indent is None:
270
+ indent = ''
271
+ if firstline_indent is None:
272
+ firstline_indent = indent
273
+
274
+ if len(indent) >= length:
275
+ raise ValueError('Length of indent exceeds length')
276
+ if len(firstline_indent) >= length:
277
+ raise ValueError('Length of first line indent exceeds length')
278
+
279
+ text = text.expandtabs(4)
280
+
281
+ result = []
282
+ # Create one wrapper for the first paragraph and one for subsequent
283
+ # paragraphs that does not have the initial wrapping.
284
+ wrapper = textwrap.TextWrapper(
285
+ width=length, initial_indent=firstline_indent, subsequent_indent=indent)
286
+ subsequent_wrapper = textwrap.TextWrapper(
287
+ width=length, initial_indent=indent, subsequent_indent=indent)
288
+
289
+ # textwrap does not have any special treatment for newlines. From the docs:
290
+ # "...newlines may appear in the middle of a line and cause strange output.
291
+ # For this reason, text should be split into paragraphs (using
292
+ # str.splitlines() or similar) which are wrapped separately."
293
+ for paragraph in (p.strip() for p in text.splitlines()):
294
+ if paragraph:
295
+ result.extend(wrapper.wrap(paragraph))
296
+ else:
297
+ result.append('') # Keep empty lines.
298
+ # Replace initial wrapper with wrapper for subsequent paragraphs.
299
+ wrapper = subsequent_wrapper
300
+
301
+ return '\n'.join(result)
302
+
303
+
304
+ def flag_dict_to_args(
305
+ flag_map: Dict[str, Any], multi_flags: Optional[Set[str]] = None
306
+ ) -> Iterable[str]:
307
+ """Convert a dict of values into process call parameters.
308
+
309
+ This method is used to convert a dictionary into a sequence of parameters
310
+ for a binary that parses arguments using this module.
311
+
312
+ Args:
313
+ flag_map: dict, a mapping where the keys are flag names (strings).
314
+ values are treated according to their type:
315
+
316
+ * If value is ``None``, then only the name is emitted.
317
+ * If value is ``True``, then only the name is emitted.
318
+ * If value is ``False``, then only the name prepended with 'no' is
319
+ emitted.
320
+ * If value is a string then ``--name=value`` is emitted.
321
+ * If value is a collection, this will emit
322
+ ``--name=value1,value2,value3``, unless the flag name is in
323
+ ``multi_flags``, in which case this will emit
324
+ ``--name=value1 --name=value2 --name=value3``.
325
+ * Everything else is converted to string an passed as such.
326
+
327
+ multi_flags: set, names (strings) of flags that should be treated as
328
+ multi-flags.
329
+ Yields:
330
+ sequence of string suitable for a subprocess execution.
331
+ """
332
+ for key, value in flag_map.items():
333
+ if value is None:
334
+ yield '--%s' % key
335
+ elif isinstance(value, bool):
336
+ if value:
337
+ yield '--%s' % key
338
+ else:
339
+ yield '--no%s' % key
340
+ elif isinstance(value, (bytes, type(u''))):
341
+ # We don't want strings to be handled like python collections.
342
+ yield '--%s=%s' % (key, value)
343
+ else:
344
+ # Now we attempt to deal with collections.
345
+ try:
346
+ if multi_flags and key in multi_flags:
347
+ for item in value:
348
+ yield '--%s=%s' % (key, str(item))
349
+ else:
350
+ yield '--%s=%s' % (key, ','.join(str(item) for item in value))
351
+ except TypeError:
352
+ # Default case.
353
+ yield '--%s=%s' % (key, value)
354
+
355
+
356
+ def trim_docstring(docstring: str) -> str:
357
+ """Removes indentation from triple-quoted strings.
358
+
359
+ This is the function specified in PEP 257 to handle docstrings:
360
+ https://www.python.org/dev/peps/pep-0257/.
361
+
362
+ Args:
363
+ docstring: str, a python docstring.
364
+
365
+ Returns:
366
+ str, docstring with indentation removed.
367
+ """
368
+ if not docstring:
369
+ return ''
370
+
371
+ # If you've got a line longer than this you have other problems...
372
+ max_indent = 1 << 29
373
+
374
+ # Convert tabs to spaces (following the normal Python rules)
375
+ # and split into a list of lines:
376
+ lines = docstring.expandtabs().splitlines()
377
+
378
+ # Determine minimum indentation (first line doesn't count):
379
+ indent = max_indent
380
+ for line in lines[1:]:
381
+ stripped = line.lstrip()
382
+ if stripped:
383
+ indent = min(indent, len(line) - len(stripped))
384
+ # Remove indentation (first line is special):
385
+ trimmed = [lines[0].strip()]
386
+ if indent < max_indent:
387
+ for line in lines[1:]:
388
+ trimmed.append(line[indent:].rstrip())
389
+ # Strip off trailing and leading blank lines:
390
+ while trimmed and not trimmed[-1]:
391
+ trimmed.pop()
392
+ while trimmed and not trimmed[0]:
393
+ trimmed.pop(0)
394
+ # Return a single string:
395
+ return '\n'.join(trimmed)
396
+
397
+
398
+ def doc_to_help(doc: str) -> str:
399
+ """Takes a __doc__ string and reformats it as help."""
400
+
401
+ # Get rid of starting and ending white space. Using lstrip() or even
402
+ # strip() could drop more than maximum of first line and right space
403
+ # of last line.
404
+ doc = doc.strip()
405
+
406
+ # Get rid of all empty lines.
407
+ whitespace_only_line = re.compile('^[ \t]+$', re.M)
408
+ doc = whitespace_only_line.sub('', doc)
409
+
410
+ # Cut out common space at line beginnings.
411
+ doc = trim_docstring(doc)
412
+
413
+ # Just like this module's comment, comments tend to be aligned somehow.
414
+ # In other words they all start with the same amount of white space.
415
+ # 1) keep double new lines;
416
+ # 2) keep ws after new lines if not empty line;
417
+ # 3) all other new lines shall be changed to a space;
418
+ # Solution: Match new lines between non white space and replace with space.
419
+ doc = re.sub(r'(?<=\S)\n(?=\S)', ' ', doc, flags=re.M)
420
+
421
+ return doc
MLPY/Lib/site-packages/absl/flags/_validators.py ADDED
@@ -0,0 +1,352 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2017 The Abseil Authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Module to enforce different constraints on flags.
16
+
17
+ Flags validators can be registered using following functions / decorators::
18
+
19
+ flags.register_validator
20
+ @flags.validator
21
+ flags.register_multi_flags_validator
22
+ @flags.multi_flags_validator
23
+
24
+ Three convenience functions are also provided for common flag constraints::
25
+
26
+ flags.mark_flag_as_required
27
+ flags.mark_flags_as_required
28
+ flags.mark_flags_as_mutual_exclusive
29
+ flags.mark_bool_flags_as_mutual_exclusive
30
+
31
+ See their docstring in this module for a usage manual.
32
+
33
+ Do NOT import this module directly. Import the flags package and use the
34
+ aliases defined at the package level instead.
35
+ """
36
+
37
+ import warnings
38
+
39
+ from absl.flags import _exceptions
40
+ from absl.flags import _flagvalues
41
+ from absl.flags import _validators_classes
42
+
43
+
44
+ def register_validator(flag_name,
45
+ checker,
46
+ message='Flag validation failed',
47
+ flag_values=_flagvalues.FLAGS):
48
+ """Adds a constraint, which will be enforced during program execution.
49
+
50
+ The constraint is validated when flags are initially parsed, and after each
51
+ change of the corresponding flag's value.
52
+
53
+ Args:
54
+ flag_name: str | FlagHolder, name or holder of the flag to be checked.
55
+ Positional-only parameter.
56
+ checker: callable, a function to validate the flag.
57
+
58
+ * input - A single positional argument: The value of the corresponding
59
+ flag (string, boolean, etc. This value will be passed to checker
60
+ by the library).
61
+ * output - bool, True if validator constraint is satisfied.
62
+ If constraint is not satisfied, it should either ``return False`` or
63
+ ``raise flags.ValidationError(desired_error_message)``.
64
+
65
+ message: str, error text to be shown to the user if checker returns False.
66
+ If checker raises flags.ValidationError, message from the raised
67
+ error will be shown.
68
+ flag_values: flags.FlagValues, optional FlagValues instance to validate
69
+ against.
70
+
71
+ Raises:
72
+ AttributeError: Raised when flag_name is not registered as a valid flag
73
+ name.
74
+ ValueError: Raised when flag_values is non-default and does not match the
75
+ FlagValues of the provided FlagHolder instance.
76
+ """
77
+ flag_name, flag_values = _flagvalues.resolve_flag_ref(flag_name, flag_values)
78
+ v = _validators_classes.SingleFlagValidator(flag_name, checker, message)
79
+ _add_validator(flag_values, v)
80
+
81
+
82
+ def validator(flag_name, message='Flag validation failed',
83
+ flag_values=_flagvalues.FLAGS):
84
+ """A function decorator for defining a flag validator.
85
+
86
+ Registers the decorated function as a validator for flag_name, e.g.::
87
+
88
+ @flags.validator('foo')
89
+ def _CheckFoo(foo):
90
+ ...
91
+
92
+ See :func:`register_validator` for the specification of checker function.
93
+
94
+ Args:
95
+ flag_name: str | FlagHolder, name or holder of the flag to be checked.
96
+ Positional-only parameter.
97
+ message: str, error text to be shown to the user if checker returns False.
98
+ If checker raises flags.ValidationError, message from the raised
99
+ error will be shown.
100
+ flag_values: flags.FlagValues, optional FlagValues instance to validate
101
+ against.
102
+ Returns:
103
+ A function decorator that registers its function argument as a validator.
104
+ Raises:
105
+ AttributeError: Raised when flag_name is not registered as a valid flag
106
+ name.
107
+ """
108
+
109
+ def decorate(function):
110
+ register_validator(flag_name, function,
111
+ message=message,
112
+ flag_values=flag_values)
113
+ return function
114
+ return decorate
115
+
116
+
117
+ def register_multi_flags_validator(flag_names,
118
+ multi_flags_checker,
119
+ message='Flags validation failed',
120
+ flag_values=_flagvalues.FLAGS):
121
+ """Adds a constraint to multiple flags.
122
+
123
+ The constraint is validated when flags are initially parsed, and after each
124
+ change of the corresponding flag's value.
125
+
126
+ Args:
127
+ flag_names: [str | FlagHolder], a list of the flag names or holders to be
128
+ checked. Positional-only parameter.
129
+ multi_flags_checker: callable, a function to validate the flag.
130
+
131
+ * input - dict, with keys() being flag_names, and value for each key
132
+ being the value of the corresponding flag (string, boolean, etc).
133
+ * output - bool, True if validator constraint is satisfied.
134
+ If constraint is not satisfied, it should either return False or
135
+ raise flags.ValidationError.
136
+
137
+ message: str, error text to be shown to the user if checker returns False.
138
+ If checker raises flags.ValidationError, message from the raised
139
+ error will be shown.
140
+ flag_values: flags.FlagValues, optional FlagValues instance to validate
141
+ against.
142
+
143
+ Raises:
144
+ AttributeError: Raised when a flag is not registered as a valid flag name.
145
+ ValueError: Raised when multiple FlagValues are used in the same
146
+ invocation. This can occur when FlagHolders have different `_flagvalues`
147
+ or when str-type flag_names entries are present and the `flag_values`
148
+ argument does not match that of provided FlagHolder(s).
149
+ """
150
+ flag_names, flag_values = _flagvalues.resolve_flag_refs(
151
+ flag_names, flag_values)
152
+ v = _validators_classes.MultiFlagsValidator(
153
+ flag_names, multi_flags_checker, message)
154
+ _add_validator(flag_values, v)
155
+
156
+
157
+ def multi_flags_validator(flag_names,
158
+ message='Flag validation failed',
159
+ flag_values=_flagvalues.FLAGS):
160
+ """A function decorator for defining a multi-flag validator.
161
+
162
+ Registers the decorated function as a validator for flag_names, e.g.::
163
+
164
+ @flags.multi_flags_validator(['foo', 'bar'])
165
+ def _CheckFooBar(flags_dict):
166
+ ...
167
+
168
+ See :func:`register_multi_flags_validator` for the specification of checker
169
+ function.
170
+
171
+ Args:
172
+ flag_names: [str | FlagHolder], a list of the flag names or holders to be
173
+ checked. Positional-only parameter.
174
+ message: str, error text to be shown to the user if checker returns False.
175
+ If checker raises flags.ValidationError, message from the raised
176
+ error will be shown.
177
+ flag_values: flags.FlagValues, optional FlagValues instance to validate
178
+ against.
179
+
180
+ Returns:
181
+ A function decorator that registers its function argument as a validator.
182
+
183
+ Raises:
184
+ AttributeError: Raised when a flag is not registered as a valid flag name.
185
+ """
186
+
187
+ def decorate(function):
188
+ register_multi_flags_validator(flag_names,
189
+ function,
190
+ message=message,
191
+ flag_values=flag_values)
192
+ return function
193
+
194
+ return decorate
195
+
196
+
197
+ def mark_flag_as_required(flag_name, flag_values=_flagvalues.FLAGS):
198
+ """Ensures that flag is not None during program execution.
199
+
200
+ Registers a flag validator, which will follow usual validator rules.
201
+ Important note: validator will pass for any non-``None`` value, such as
202
+ ``False``, ``0`` (zero), ``''`` (empty string) and so on.
203
+
204
+ If your module might be imported by others, and you only wish to make the flag
205
+ required when the module is directly executed, call this method like this::
206
+
207
+ if __name__ == '__main__':
208
+ flags.mark_flag_as_required('your_flag_name')
209
+ app.run()
210
+
211
+ Args:
212
+ flag_name: str | FlagHolder, name or holder of the flag.
213
+ Positional-only parameter.
214
+ flag_values: flags.FlagValues, optional :class:`~absl.flags.FlagValues`
215
+ instance where the flag is defined.
216
+ Raises:
217
+ AttributeError: Raised when flag_name is not registered as a valid flag
218
+ name.
219
+ ValueError: Raised when flag_values is non-default and does not match the
220
+ FlagValues of the provided FlagHolder instance.
221
+ """
222
+ flag_name, flag_values = _flagvalues.resolve_flag_ref(flag_name, flag_values)
223
+ if flag_values[flag_name].default is not None:
224
+ warnings.warn(
225
+ 'Flag --%s has a non-None default value; therefore, '
226
+ 'mark_flag_as_required will pass even if flag is not specified in the '
227
+ 'command line!' % flag_name,
228
+ stacklevel=2)
229
+ register_validator(
230
+ flag_name,
231
+ lambda value: value is not None,
232
+ message='Flag --{} must have a value other than None.'.format(flag_name),
233
+ flag_values=flag_values)
234
+
235
+
236
+ def mark_flags_as_required(flag_names, flag_values=_flagvalues.FLAGS):
237
+ """Ensures that flags are not None during program execution.
238
+
239
+ If your module might be imported by others, and you only wish to make the flag
240
+ required when the module is directly executed, call this method like this::
241
+
242
+ if __name__ == '__main__':
243
+ flags.mark_flags_as_required(['flag1', 'flag2', 'flag3'])
244
+ app.run()
245
+
246
+ Args:
247
+ flag_names: Sequence[str | FlagHolder], names or holders of the flags.
248
+ flag_values: flags.FlagValues, optional FlagValues instance where the flags
249
+ are defined.
250
+ Raises:
251
+ AttributeError: If any of flag name has not already been defined as a flag.
252
+ """
253
+ for flag_name in flag_names:
254
+ mark_flag_as_required(flag_name, flag_values)
255
+
256
+
257
+ def mark_flags_as_mutual_exclusive(flag_names, required=False,
258
+ flag_values=_flagvalues.FLAGS):
259
+ """Ensures that only one flag among flag_names is not None.
260
+
261
+ Important note: This validator checks if flag values are ``None``, and it does
262
+ not distinguish between default and explicit values. Therefore, this validator
263
+ does not make sense when applied to flags with default values other than None,
264
+ including other false values (e.g. ``False``, ``0``, ``''``, ``[]``). That
265
+ includes multi flags with a default value of ``[]`` instead of None.
266
+
267
+ Args:
268
+ flag_names: [str | FlagHolder], names or holders of flags.
269
+ Positional-only parameter.
270
+ required: bool. If true, exactly one of the flags must have a value other
271
+ than None. Otherwise, at most one of the flags can have a value other
272
+ than None, and it is valid for all of the flags to be None.
273
+ flag_values: flags.FlagValues, optional FlagValues instance where the flags
274
+ are defined.
275
+
276
+ Raises:
277
+ ValueError: Raised when multiple FlagValues are used in the same
278
+ invocation. This can occur when FlagHolders have different `_flagvalues`
279
+ or when str-type flag_names entries are present and the `flag_values`
280
+ argument does not match that of provided FlagHolder(s).
281
+ """
282
+ flag_names, flag_values = _flagvalues.resolve_flag_refs(
283
+ flag_names, flag_values)
284
+ for flag_name in flag_names:
285
+ if flag_values[flag_name].default is not None:
286
+ warnings.warn(
287
+ 'Flag --{} has a non-None default value. That does not make sense '
288
+ 'with mark_flags_as_mutual_exclusive, which checks whether the '
289
+ 'listed flags have a value other than None.'.format(flag_name),
290
+ stacklevel=2)
291
+
292
+ def validate_mutual_exclusion(flags_dict):
293
+ flag_count = sum(1 for val in flags_dict.values() if val is not None)
294
+ if flag_count == 1 or (not required and flag_count == 0):
295
+ return True
296
+ raise _exceptions.ValidationError(
297
+ '{} one of ({}) must have a value other than None.'.format(
298
+ 'Exactly' if required else 'At most', ', '.join(flag_names)))
299
+
300
+ register_multi_flags_validator(
301
+ flag_names, validate_mutual_exclusion, flag_values=flag_values)
302
+
303
+
304
+ def mark_bool_flags_as_mutual_exclusive(flag_names, required=False,
305
+ flag_values=_flagvalues.FLAGS):
306
+ """Ensures that only one flag among flag_names is True.
307
+
308
+ Args:
309
+ flag_names: [str | FlagHolder], names or holders of flags.
310
+ Positional-only parameter.
311
+ required: bool. If true, exactly one flag must be True. Otherwise, at most
312
+ one flag can be True, and it is valid for all flags to be False.
313
+ flag_values: flags.FlagValues, optional FlagValues instance where the flags
314
+ are defined.
315
+
316
+ Raises:
317
+ ValueError: Raised when multiple FlagValues are used in the same
318
+ invocation. This can occur when FlagHolders have different `_flagvalues`
319
+ or when str-type flag_names entries are present and the `flag_values`
320
+ argument does not match that of provided FlagHolder(s).
321
+ """
322
+ flag_names, flag_values = _flagvalues.resolve_flag_refs(
323
+ flag_names, flag_values)
324
+ for flag_name in flag_names:
325
+ if not flag_values[flag_name].boolean:
326
+ raise _exceptions.ValidationError(
327
+ 'Flag --{} is not Boolean, which is required for flags used in '
328
+ 'mark_bool_flags_as_mutual_exclusive.'.format(flag_name))
329
+
330
+ def validate_boolean_mutual_exclusion(flags_dict):
331
+ flag_count = sum(bool(val) for val in flags_dict.values())
332
+ if flag_count == 1 or (not required and flag_count == 0):
333
+ return True
334
+ raise _exceptions.ValidationError(
335
+ '{} one of ({}) must be True.'.format(
336
+ 'Exactly' if required else 'At most', ', '.join(flag_names)))
337
+
338
+ register_multi_flags_validator(
339
+ flag_names, validate_boolean_mutual_exclusion, flag_values=flag_values)
340
+
341
+
342
+ def _add_validator(fv, validator_instance):
343
+ """Register new flags validator to be checked.
344
+
345
+ Args:
346
+ fv: flags.FlagValues, the FlagValues instance to add the validator.
347
+ validator_instance: validators.Validator, the validator to add.
348
+ Raises:
349
+ KeyError: Raised when validators work with a non-existing flag.
350
+ """
351
+ for flag_name in validator_instance.get_flags_names():
352
+ fv[flag_name].validators.append(validator_instance)
MLPY/Lib/site-packages/absl/flags/_validators_classes.py ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2021 The Abseil Authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Defines *private* classes used for flag validators.
16
+
17
+ Do NOT import this module. DO NOT use anything from this module. They are
18
+ private APIs.
19
+ """
20
+
21
+ from absl.flags import _exceptions
22
+
23
+
24
+ class Validator(object):
25
+ """Base class for flags validators.
26
+
27
+ Users should NOT overload these classes, and use flags.Register...
28
+ methods instead.
29
+ """
30
+
31
+ # Used to assign each validator an unique insertion_index
32
+ validators_count = 0
33
+
34
+ def __init__(self, checker, message):
35
+ """Constructor to create all validators.
36
+
37
+ Args:
38
+ checker: function to verify the constraint.
39
+ Input of this method varies, see SingleFlagValidator and
40
+ multi_flags_validator for a detailed description.
41
+ message: str, error message to be shown to the user.
42
+ """
43
+ self.checker = checker
44
+ self.message = message
45
+ Validator.validators_count += 1
46
+ # Used to assert validators in the order they were registered.
47
+ self.insertion_index = Validator.validators_count
48
+
49
+ def verify(self, flag_values):
50
+ """Verifies that constraint is satisfied.
51
+
52
+ flags library calls this method to verify Validator's constraint.
53
+
54
+ Args:
55
+ flag_values: flags.FlagValues, the FlagValues instance to get flags from.
56
+ Raises:
57
+ Error: Raised if constraint is not satisfied.
58
+ """
59
+ param = self._get_input_to_checker_function(flag_values)
60
+ if not self.checker(param):
61
+ raise _exceptions.ValidationError(self.message)
62
+
63
+ def get_flags_names(self):
64
+ """Returns the names of the flags checked by this validator.
65
+
66
+ Returns:
67
+ [string], names of the flags.
68
+ """
69
+ raise NotImplementedError('This method should be overloaded')
70
+
71
+ def print_flags_with_values(self, flag_values):
72
+ raise NotImplementedError('This method should be overloaded')
73
+
74
+ def _get_input_to_checker_function(self, flag_values):
75
+ """Given flag values, returns the input to be given to checker.
76
+
77
+ Args:
78
+ flag_values: flags.FlagValues, containing all flags.
79
+ Returns:
80
+ The input to be given to checker. The return type depends on the specific
81
+ validator.
82
+ """
83
+ raise NotImplementedError('This method should be overloaded')
84
+
85
+
86
+ class SingleFlagValidator(Validator):
87
+ """Validator behind register_validator() method.
88
+
89
+ Validates that a single flag passes its checker function. The checker function
90
+ takes the flag value and returns True (if value looks fine) or, if flag value
91
+ is not valid, either returns False or raises an Exception.
92
+ """
93
+
94
+ def __init__(self, flag_name, checker, message):
95
+ """Constructor.
96
+
97
+ Args:
98
+ flag_name: string, name of the flag.
99
+ checker: function to verify the validator.
100
+ input - value of the corresponding flag (string, boolean, etc).
101
+ output - bool, True if validator constraint is satisfied.
102
+ If constraint is not satisfied, it should either return False or
103
+ raise flags.ValidationError(desired_error_message).
104
+ message: str, error message to be shown to the user if validator's
105
+ condition is not satisfied.
106
+ """
107
+ super(SingleFlagValidator, self).__init__(checker, message)
108
+ self.flag_name = flag_name
109
+
110
+ def get_flags_names(self):
111
+ return [self.flag_name]
112
+
113
+ def print_flags_with_values(self, flag_values):
114
+ return 'flag --%s=%s' % (self.flag_name, flag_values[self.flag_name].value)
115
+
116
+ def _get_input_to_checker_function(self, flag_values):
117
+ """Given flag values, returns the input to be given to checker.
118
+
119
+ Args:
120
+ flag_values: flags.FlagValues, the FlagValues instance to get flags from.
121
+ Returns:
122
+ object, the input to be given to checker.
123
+ """
124
+ return flag_values[self.flag_name].value
125
+
126
+
127
+ class MultiFlagsValidator(Validator):
128
+ """Validator behind register_multi_flags_validator method.
129
+
130
+ Validates that flag values pass their common checker function. The checker
131
+ function takes flag values and returns True (if values look fine) or,
132
+ if values are not valid, either returns False or raises an Exception.
133
+ """
134
+
135
+ def __init__(self, flag_names, checker, message):
136
+ """Constructor.
137
+
138
+ Args:
139
+ flag_names: [str], containing names of the flags used by checker.
140
+ checker: function to verify the validator.
141
+ input - dict, with keys() being flag_names, and value for each
142
+ key being the value of the corresponding flag (string, boolean,
143
+ etc).
144
+ output - bool, True if validator constraint is satisfied.
145
+ If constraint is not satisfied, it should either return False or
146
+ raise flags.ValidationError(desired_error_message).
147
+ message: str, error message to be shown to the user if validator's
148
+ condition is not satisfied
149
+ """
150
+ super(MultiFlagsValidator, self).__init__(checker, message)
151
+ self.flag_names = flag_names
152
+
153
+ def _get_input_to_checker_function(self, flag_values):
154
+ """Given flag values, returns the input to be given to checker.
155
+
156
+ Args:
157
+ flag_values: flags.FlagValues, the FlagValues instance to get flags from.
158
+ Returns:
159
+ dict, with keys() being self.flag_names, and value for each key
160
+ being the value of the corresponding flag (string, boolean, etc).
161
+ """
162
+ return dict([key, flag_values[key].value] for key in self.flag_names)
163
+
164
+ def print_flags_with_values(self, flag_values):
165
+ prefix = 'flags '
166
+ flags_with_values = []
167
+ for key in self.flag_names:
168
+ flags_with_values.append('%s=%s' % (key, flag_values[key].value))
169
+ return prefix + ', '.join(flags_with_values)
170
+
171
+ def get_flags_names(self):
172
+ return self.flag_names
MLPY/Lib/site-packages/absl/flags/argparse_flags.py ADDED
@@ -0,0 +1,388 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2018 The Abseil Authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """This module provides argparse integration with absl.flags.
16
+
17
+ ``argparse_flags.ArgumentParser`` is a drop-in replacement for
18
+ :class:`argparse.ArgumentParser`. It takes care of collecting and defining absl
19
+ flags in :mod:`argparse`.
20
+
21
+ Here is a simple example::
22
+
23
+ # Assume the following absl.flags is defined in another module:
24
+ #
25
+ # from absl import flags
26
+ # flags.DEFINE_string('echo', None, 'The echo message.')
27
+ #
28
+ parser = argparse_flags.ArgumentParser(
29
+ description='A demo of absl.flags and argparse integration.')
30
+ parser.add_argument('--header', help='Header message to print.')
31
+
32
+ # The parser will also accept the absl flag `--echo`.
33
+ # The `header` value is available as `args.header` just like a regular
34
+ # argparse flag. The absl flag `--echo` continues to be available via
35
+ # `absl.flags.FLAGS` if you want to access it.
36
+ args = parser.parse_args()
37
+
38
+ # Example usages:
39
+ # ./program --echo='A message.' --header='A header'
40
+ # ./program --header 'A header' --echo 'A message.'
41
+
42
+
43
+ Here is another example demonstrates subparsers::
44
+
45
+ parser = argparse_flags.ArgumentParser(description='A subcommands demo.')
46
+ parser.add_argument('--header', help='The header message to print.')
47
+
48
+ subparsers = parser.add_subparsers(help='The command to execute.')
49
+
50
+ roll_dice_parser = subparsers.add_parser(
51
+ 'roll_dice', help='Roll a dice.',
52
+ # By default, absl flags can also be specified after the sub-command.
53
+ # To only allow them before sub-command, pass
54
+ # `inherited_absl_flags=None`.
55
+ inherited_absl_flags=None)
56
+ roll_dice_parser.add_argument('--num_faces', type=int, default=6)
57
+ roll_dice_parser.set_defaults(command=roll_dice)
58
+
59
+ shuffle_parser = subparsers.add_parser('shuffle', help='Shuffle inputs.')
60
+ shuffle_parser.add_argument(
61
+ 'inputs', metavar='I', nargs='+', help='Inputs to shuffle.')
62
+ shuffle_parser.set_defaults(command=shuffle)
63
+
64
+ args = parser.parse_args(argv[1:])
65
+ args.command(args)
66
+
67
+ # Example usages:
68
+ # ./program --echo='A message.' roll_dice --num_faces=6
69
+ # ./program shuffle --echo='A message.' 1 2 3 4
70
+
71
+
72
+ There are several differences between :mod:`absl.flags` and
73
+ :mod:`~absl.flags.argparse_flags`:
74
+
75
+ 1. Flags defined with absl.flags are parsed differently when using the
76
+ argparse parser. Notably:
77
+
78
+ 1) absl.flags allows both single-dash and double-dash for any flag, and
79
+ doesn't distinguish them; argparse_flags only allows double-dash for
80
+ flag's regular name, and single-dash for flag's ``short_name``.
81
+ 2) Boolean flags in absl.flags can be specified with ``--bool``,
82
+ ``--nobool``, as well as ``--bool=true/false`` (though not recommended);
83
+ in argparse_flags, it only allows ``--bool``, ``--nobool``.
84
+
85
+ 2. Help related flag differences:
86
+
87
+ 1) absl.flags does not define help flags, absl.app does that; argparse_flags
88
+ defines help flags unless passed with ``add_help=False``.
89
+ 2) absl.app supports ``--helpxml``; argparse_flags does not.
90
+ 3) argparse_flags supports ``-h``; absl.app does not.
91
+ """
92
+
93
+ import argparse
94
+ import sys
95
+
96
+ from absl import flags
97
+
98
+
99
+ _BUILT_IN_FLAGS = frozenset({
100
+ 'help',
101
+ 'helpshort',
102
+ 'helpfull',
103
+ 'helpxml',
104
+ 'flagfile',
105
+ 'undefok',
106
+ })
107
+
108
+
109
+ class ArgumentParser(argparse.ArgumentParser):
110
+ """Custom ArgumentParser class to support special absl flags."""
111
+
112
+ def __init__(self, **kwargs):
113
+ """Initializes ArgumentParser.
114
+
115
+ Args:
116
+ **kwargs: same as argparse.ArgumentParser, except:
117
+ 1. It also accepts `inherited_absl_flags`: the absl flags to inherit.
118
+ The default is the global absl.flags.FLAGS instance. Pass None to
119
+ ignore absl flags.
120
+ 2. The `prefix_chars` argument must be the default value '-'.
121
+
122
+ Raises:
123
+ ValueError: Raised when prefix_chars is not '-'.
124
+ """
125
+ prefix_chars = kwargs.get('prefix_chars', '-')
126
+ if prefix_chars != '-':
127
+ raise ValueError(
128
+ 'argparse_flags.ArgumentParser only supports "-" as the prefix '
129
+ 'character, found "{}".'.format(prefix_chars))
130
+
131
+ # Remove inherited_absl_flags before calling super.
132
+ self._inherited_absl_flags = kwargs.pop('inherited_absl_flags', flags.FLAGS)
133
+ # Now call super to initialize argparse.ArgumentParser before calling
134
+ # add_argument in _define_absl_flags.
135
+ super(ArgumentParser, self).__init__(**kwargs)
136
+
137
+ if self.add_help:
138
+ # -h and --help are defined in super.
139
+ # Also add the --helpshort and --helpfull flags.
140
+ self.add_argument(
141
+ # Action 'help' defines a similar flag to -h/--help.
142
+ '--helpshort', action='help',
143
+ default=argparse.SUPPRESS, help=argparse.SUPPRESS)
144
+ self.add_argument(
145
+ '--helpfull', action=_HelpFullAction,
146
+ default=argparse.SUPPRESS, help='show full help message and exit')
147
+
148
+ if self._inherited_absl_flags is not None:
149
+ self.add_argument(
150
+ '--undefok', default=argparse.SUPPRESS, help=argparse.SUPPRESS)
151
+ self._define_absl_flags(self._inherited_absl_flags)
152
+
153
+ def parse_known_args(self, args=None, namespace=None):
154
+ if args is None:
155
+ args = sys.argv[1:]
156
+ if self._inherited_absl_flags is not None:
157
+ # Handle --flagfile.
158
+ # Explicitly specify force_gnu=True, since argparse behaves like
159
+ # gnu_getopt: flags can be specified after positional arguments.
160
+ args = self._inherited_absl_flags.read_flags_from_files(
161
+ args, force_gnu=True)
162
+
163
+ undefok_missing = object()
164
+ undefok = getattr(namespace, 'undefok', undefok_missing)
165
+
166
+ namespace, args = super(ArgumentParser, self).parse_known_args(
167
+ args, namespace)
168
+
169
+ # For Python <= 2.7.8: https://bugs.python.org/issue9351, a bug where
170
+ # sub-parsers don't preserve existing namespace attributes.
171
+ # Restore the undefok attribute if a sub-parser dropped it.
172
+ if undefok is not undefok_missing:
173
+ namespace.undefok = undefok
174
+
175
+ if self._inherited_absl_flags is not None:
176
+ # Handle --undefok. At this point, `args` only contains unknown flags,
177
+ # so it won't strip defined flags that are also specified with --undefok.
178
+ # For Python <= 2.7.8: https://bugs.python.org/issue9351, a bug where
179
+ # sub-parsers don't preserve existing namespace attributes. The undefok
180
+ # attribute might not exist because a subparser dropped it.
181
+ if hasattr(namespace, 'undefok'):
182
+ args = _strip_undefok_args(namespace.undefok, args)
183
+ # absl flags are not exposed in the Namespace object. See Namespace:
184
+ # https://docs.python.org/3/library/argparse.html#argparse.Namespace.
185
+ del namespace.undefok
186
+ self._inherited_absl_flags.mark_as_parsed()
187
+ try:
188
+ self._inherited_absl_flags.validate_all_flags()
189
+ except flags.IllegalFlagValueError as e:
190
+ self.error(str(e))
191
+
192
+ return namespace, args
193
+
194
+ def _define_absl_flags(self, absl_flags):
195
+ """Defines flags from absl_flags."""
196
+ key_flags = set(absl_flags.get_key_flags_for_module(sys.argv[0]))
197
+ for name in absl_flags:
198
+ if name in _BUILT_IN_FLAGS:
199
+ # Do not inherit built-in flags.
200
+ continue
201
+ flag_instance = absl_flags[name]
202
+ # Each flags with short_name appears in FLAGS twice, so only define
203
+ # when the dictionary key is equal to the regular name.
204
+ if name == flag_instance.name:
205
+ # Suppress the flag in the help short message if it's not a main
206
+ # module's key flag.
207
+ suppress = flag_instance not in key_flags
208
+ self._define_absl_flag(flag_instance, suppress)
209
+
210
+ def _define_absl_flag(self, flag_instance, suppress):
211
+ """Defines a flag from the flag_instance."""
212
+ flag_name = flag_instance.name
213
+ short_name = flag_instance.short_name
214
+ argument_names = ['--' + flag_name]
215
+ if short_name:
216
+ argument_names.insert(0, '-' + short_name)
217
+ if suppress:
218
+ helptext = argparse.SUPPRESS
219
+ else:
220
+ # argparse help string uses %-formatting. Escape the literal %'s.
221
+ helptext = flag_instance.help.replace('%', '%%')
222
+ if flag_instance.boolean:
223
+ # Only add the `no` form to the long name.
224
+ argument_names.append('--no' + flag_name)
225
+ self.add_argument(
226
+ *argument_names, action=_BooleanFlagAction, help=helptext,
227
+ metavar=flag_instance.name.upper(),
228
+ flag_instance=flag_instance)
229
+ else:
230
+ self.add_argument(
231
+ *argument_names, action=_FlagAction, help=helptext,
232
+ metavar=flag_instance.name.upper(),
233
+ flag_instance=flag_instance)
234
+
235
+
236
+ class _FlagAction(argparse.Action):
237
+ """Action class for Abseil non-boolean flags."""
238
+
239
+ def __init__(
240
+ self,
241
+ option_strings,
242
+ dest,
243
+ help, # pylint: disable=redefined-builtin
244
+ metavar,
245
+ flag_instance,
246
+ default=argparse.SUPPRESS):
247
+ """Initializes _FlagAction.
248
+
249
+ Args:
250
+ option_strings: See argparse.Action.
251
+ dest: Ignored. The flag is always defined with dest=argparse.SUPPRESS.
252
+ help: See argparse.Action.
253
+ metavar: See argparse.Action.
254
+ flag_instance: absl.flags.Flag, the absl flag instance.
255
+ default: Ignored. The flag always uses dest=argparse.SUPPRESS so it
256
+ doesn't affect the parsing result.
257
+ """
258
+ del dest
259
+ self._flag_instance = flag_instance
260
+ super(_FlagAction, self).__init__(
261
+ option_strings=option_strings,
262
+ dest=argparse.SUPPRESS,
263
+ help=help,
264
+ metavar=metavar)
265
+
266
+ def __call__(self, parser, namespace, values, option_string=None):
267
+ """See https://docs.python.org/3/library/argparse.html#action-classes."""
268
+ self._flag_instance.parse(values)
269
+ self._flag_instance.using_default_value = False
270
+
271
+
272
+ class _BooleanFlagAction(argparse.Action):
273
+ """Action class for Abseil boolean flags."""
274
+
275
+ def __init__(
276
+ self,
277
+ option_strings,
278
+ dest,
279
+ help, # pylint: disable=redefined-builtin
280
+ metavar,
281
+ flag_instance,
282
+ default=argparse.SUPPRESS):
283
+ """Initializes _BooleanFlagAction.
284
+
285
+ Args:
286
+ option_strings: See argparse.Action.
287
+ dest: Ignored. The flag is always defined with dest=argparse.SUPPRESS.
288
+ help: See argparse.Action.
289
+ metavar: See argparse.Action.
290
+ flag_instance: absl.flags.Flag, the absl flag instance.
291
+ default: Ignored. The flag always uses dest=argparse.SUPPRESS so it
292
+ doesn't affect the parsing result.
293
+ """
294
+ del dest, default
295
+ self._flag_instance = flag_instance
296
+ flag_names = [self._flag_instance.name]
297
+ if self._flag_instance.short_name:
298
+ flag_names.append(self._flag_instance.short_name)
299
+ self._flag_names = frozenset(flag_names)
300
+ super(_BooleanFlagAction, self).__init__(
301
+ option_strings=option_strings,
302
+ dest=argparse.SUPPRESS,
303
+ nargs=0, # Does not accept values, only `--bool` or `--nobool`.
304
+ help=help,
305
+ metavar=metavar)
306
+
307
+ def __call__(self, parser, namespace, values, option_string=None):
308
+ """See https://docs.python.org/3/library/argparse.html#action-classes."""
309
+ if not isinstance(values, list) or values:
310
+ raise ValueError('values must be an empty list.')
311
+ if option_string.startswith('--'):
312
+ option = option_string[2:]
313
+ else:
314
+ option = option_string[1:]
315
+ if option in self._flag_names:
316
+ self._flag_instance.parse('true')
317
+ else:
318
+ if not option.startswith('no') or option[2:] not in self._flag_names:
319
+ raise ValueError('invalid option_string: ' + option_string)
320
+ self._flag_instance.parse('false')
321
+ self._flag_instance.using_default_value = False
322
+
323
+
324
+ class _HelpFullAction(argparse.Action):
325
+ """Action class for --helpfull flag."""
326
+
327
+ def __init__(self, option_strings, dest, default, help): # pylint: disable=redefined-builtin
328
+ """Initializes _HelpFullAction.
329
+
330
+ Args:
331
+ option_strings: See argparse.Action.
332
+ dest: Ignored. The flag is always defined with dest=argparse.SUPPRESS.
333
+ default: Ignored.
334
+ help: See argparse.Action.
335
+ """
336
+ del dest, default
337
+ super(_HelpFullAction, self).__init__(
338
+ option_strings=option_strings,
339
+ dest=argparse.SUPPRESS,
340
+ default=argparse.SUPPRESS,
341
+ nargs=0,
342
+ help=help)
343
+
344
+ def __call__(self, parser, namespace, values, option_string=None):
345
+ """See https://docs.python.org/3/library/argparse.html#action-classes."""
346
+ # This only prints flags when help is not argparse.SUPPRESS.
347
+ # It includes user defined argparse flags, as well as main module's
348
+ # key absl flags. Other absl flags use argparse.SUPPRESS, so they aren't
349
+ # printed here.
350
+ parser.print_help()
351
+
352
+ absl_flags = parser._inherited_absl_flags # pylint: disable=protected-access
353
+ if absl_flags is not None:
354
+ modules = sorted(absl_flags.flags_by_module_dict())
355
+ main_module = sys.argv[0]
356
+ if main_module in modules:
357
+ # The main module flags are already printed in parser.print_help().
358
+ modules.remove(main_module)
359
+ print(absl_flags._get_help_for_modules( # pylint: disable=protected-access
360
+ modules, prefix='', include_special_flags=True))
361
+ parser.exit()
362
+
363
+
364
+ def _strip_undefok_args(undefok, args):
365
+ """Returns a new list of args after removing flags in --undefok."""
366
+ if undefok:
367
+ undefok_names = set(name.strip() for name in undefok.split(','))
368
+ undefok_names |= set('no' + name for name in undefok_names)
369
+ # Remove undefok flags.
370
+ args = [arg for arg in args if not _is_undefok(arg, undefok_names)]
371
+ return args
372
+
373
+
374
+ def _is_undefok(arg, undefok_names):
375
+ """Returns whether we can ignore arg based on a set of undefok flag names."""
376
+ if not arg.startswith('-'):
377
+ return False
378
+ if arg.startswith('--'):
379
+ arg_without_dash = arg[2:]
380
+ else:
381
+ arg_without_dash = arg[1:]
382
+ if '=' in arg_without_dash:
383
+ name, _ = arg_without_dash.split('=', 1)
384
+ else:
385
+ name = arg_without_dash
386
+ if name in undefok_names:
387
+ return True
388
+ return False
MLPY/Lib/site-packages/absl/logging/__init__.py ADDED
@@ -0,0 +1,1281 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2017 The Abseil Authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Abseil Python logging module implemented on top of standard logging.
16
+
17
+ Simple usage::
18
+
19
+ from absl import logging
20
+
21
+ logging.info('Interesting Stuff')
22
+ logging.info('Interesting Stuff with Arguments: %d', 42)
23
+
24
+ logging.set_verbosity(logging.INFO)
25
+ logging.log(logging.DEBUG, 'This will *not* be printed')
26
+ logging.set_verbosity(logging.DEBUG)
27
+ logging.log(logging.DEBUG, 'This will be printed')
28
+
29
+ logging.warning('Worrying Stuff')
30
+ logging.error('Alarming Stuff')
31
+ logging.fatal('AAAAHHHHH!!!!') # Process exits.
32
+
33
+ Usage note: Do not pre-format the strings in your program code.
34
+ Instead, let the logging module perform argument interpolation.
35
+ This saves cycles because strings that don't need to be printed
36
+ are never formatted. Note that this module does not attempt to
37
+ interpolate arguments when no arguments are given. In other words::
38
+
39
+ logging.info('Interesting Stuff: %s')
40
+
41
+ does not raise an exception because logging.info() has only one
42
+ argument, the message string.
43
+
44
+ "Lazy" evaluation for debugging
45
+ -------------------------------
46
+
47
+ If you do something like this::
48
+
49
+ logging.debug('Thing: %s', thing.ExpensiveOp())
50
+
51
+ then the ExpensiveOp will be evaluated even if nothing
52
+ is printed to the log. To avoid this, use the level_debug() function::
53
+
54
+ if logging.level_debug():
55
+ logging.debug('Thing: %s', thing.ExpensiveOp())
56
+
57
+ Per file level logging is supported by logging.vlog() and
58
+ logging.vlog_is_on(). For example::
59
+
60
+ if logging.vlog_is_on(2):
61
+ logging.vlog(2, very_expensive_debug_message())
62
+
63
+ Notes on Unicode
64
+ ----------------
65
+
66
+ The log output is encoded as UTF-8. Don't pass data in other encodings in
67
+ bytes() instances -- instead pass unicode string instances when you need to
68
+ (for both the format string and arguments).
69
+
70
+ Note on critical and fatal:
71
+ Standard logging module defines fatal as an alias to critical, but it's not
72
+ documented, and it does NOT actually terminate the program.
73
+ This module only defines fatal but not critical, and it DOES terminate the
74
+ program.
75
+
76
+ The differences in behavior are historical and unfortunate.
77
+ """
78
+
79
+ import collections
80
+ from collections import abc
81
+ import getpass
82
+ import io
83
+ import itertools
84
+ import logging
85
+ import os
86
+ import socket
87
+ import struct
88
+ import sys
89
+ import tempfile
90
+ import threading
91
+ import time
92
+ import timeit
93
+ import traceback
94
+ import types
95
+ import warnings
96
+
97
+ from absl import flags
98
+ from absl.logging import converter
99
+
100
+ # pylint: disable=g-import-not-at-top
101
+ try:
102
+ from typing import NoReturn
103
+ except ImportError:
104
+ pass
105
+
106
+ # pylint: enable=g-import-not-at-top
107
+
108
+ FLAGS = flags.FLAGS
109
+
110
+
111
+ # Logging levels.
112
+ FATAL = converter.ABSL_FATAL
113
+ ERROR = converter.ABSL_ERROR
114
+ WARNING = converter.ABSL_WARNING
115
+ WARN = converter.ABSL_WARNING # Deprecated name.
116
+ INFO = converter.ABSL_INFO
117
+ DEBUG = converter.ABSL_DEBUG
118
+
119
+ # Regex to match/parse log line prefixes.
120
+ ABSL_LOGGING_PREFIX_REGEX = (
121
+ r'^(?P<severity>[IWEF])'
122
+ r'(?P<month>\d\d)(?P<day>\d\d) '
123
+ r'(?P<hour>\d\d):(?P<minute>\d\d):(?P<second>\d\d)'
124
+ r'\.(?P<microsecond>\d\d\d\d\d\d) +'
125
+ r'(?P<thread_id>-?\d+) '
126
+ r'(?P<filename>[a-zA-Z<][\w._<>-]+):(?P<line>\d+)')
127
+
128
+
129
+ # Mask to convert integer thread ids to unsigned quantities for logging purposes
130
+ _THREAD_ID_MASK = 2 ** (struct.calcsize('L') * 8) - 1
131
+
132
+ # Extra property set on the LogRecord created by ABSLLogger when its level is
133
+ # CRITICAL/FATAL.
134
+ _ABSL_LOG_FATAL = '_absl_log_fatal'
135
+ # Extra prefix added to the log message when a non-absl logger logs a
136
+ # CRITICAL/FATAL message.
137
+ _CRITICAL_PREFIX = 'CRITICAL - '
138
+
139
+ # Used by findCaller to skip callers from */logging/__init__.py.
140
+ _LOGGING_FILE_PREFIX = os.path.join('logging', '__init__.')
141
+
142
+ # The ABSL logger instance, initialized in _initialize().
143
+ _absl_logger = None
144
+ # The ABSL handler instance, initialized in _initialize().
145
+ _absl_handler = None
146
+
147
+
148
+ _CPP_NAME_TO_LEVELS = {
149
+ 'debug': '0', # Abseil C++ has no DEBUG level, mapping it to INFO here.
150
+ 'info': '0',
151
+ 'warning': '1',
152
+ 'warn': '1',
153
+ 'error': '2',
154
+ 'fatal': '3'
155
+ }
156
+
157
+ _CPP_LEVEL_TO_NAMES = {
158
+ '0': 'info',
159
+ '1': 'warning',
160
+ '2': 'error',
161
+ '3': 'fatal',
162
+ }
163
+
164
+
165
+ class _VerbosityFlag(flags.Flag):
166
+ """Flag class for -v/--verbosity."""
167
+
168
+ def __init__(self, *args, **kwargs):
169
+ super(_VerbosityFlag, self).__init__(
170
+ flags.IntegerParser(),
171
+ flags.ArgumentSerializer(),
172
+ *args, **kwargs)
173
+
174
+ @property
175
+ def value(self):
176
+ return self._value
177
+
178
+ @value.setter
179
+ def value(self, v):
180
+ self._value = v
181
+ self._update_logging_levels()
182
+
183
+ def _update_logging_levels(self):
184
+ """Updates absl logging levels to the current verbosity.
185
+
186
+ Visibility: module-private
187
+ """
188
+ if not _absl_logger:
189
+ return
190
+
191
+ if self._value <= converter.ABSL_DEBUG:
192
+ standard_verbosity = converter.absl_to_standard(self._value)
193
+ else:
194
+ # --verbosity is set to higher than 1 for vlog.
195
+ standard_verbosity = logging.DEBUG - (self._value - 1)
196
+
197
+ # Also update root level when absl_handler is used.
198
+ if _absl_handler in logging.root.handlers:
199
+ # Make absl logger inherit from the root logger. absl logger might have
200
+ # a non-NOTSET value if logging.set_verbosity() is called at import time.
201
+ _absl_logger.setLevel(logging.NOTSET)
202
+ logging.root.setLevel(standard_verbosity)
203
+ else:
204
+ _absl_logger.setLevel(standard_verbosity)
205
+
206
+
207
+ class _LoggerLevelsFlag(flags.Flag):
208
+ """Flag class for --logger_levels."""
209
+
210
+ def __init__(self, *args, **kwargs):
211
+ super(_LoggerLevelsFlag, self).__init__(
212
+ _LoggerLevelsParser(),
213
+ _LoggerLevelsSerializer(),
214
+ *args, **kwargs)
215
+
216
+ @property
217
+ def value(self):
218
+ # For lack of an immutable type, be defensive and return a copy.
219
+ # Modifications to the dict aren't supported and won't have any affect.
220
+ # While Py3 could use MappingProxyType, that isn't deepcopy friendly, so
221
+ # just return a copy.
222
+ return self._value.copy()
223
+
224
+ @value.setter
225
+ def value(self, v):
226
+ self._value = {} if v is None else v
227
+ self._update_logger_levels()
228
+
229
+ def _update_logger_levels(self):
230
+ # Visibility: module-private.
231
+ # This is called by absl.app.run() during initialization.
232
+ for name, level in self._value.items():
233
+ logging.getLogger(name).setLevel(level)
234
+
235
+
236
+ class _LoggerLevelsParser(flags.ArgumentParser):
237
+ """Parser for --logger_levels flag."""
238
+
239
+ def parse(self, value):
240
+ if isinstance(value, abc.Mapping):
241
+ return value
242
+
243
+ pairs = [pair.strip() for pair in value.split(',') if pair.strip()]
244
+
245
+ # Preserve the order so that serialization is deterministic.
246
+ levels = collections.OrderedDict()
247
+ for name_level in pairs:
248
+ name, level = name_level.split(':', 1)
249
+ name = name.strip()
250
+ level = level.strip()
251
+ levels[name] = level
252
+ return levels
253
+
254
+
255
+ class _LoggerLevelsSerializer(object):
256
+ """Serializer for --logger_levels flag."""
257
+
258
+ def serialize(self, value):
259
+ if isinstance(value, str):
260
+ return value
261
+ return ','.join(
262
+ '{}:{}'.format(name, level) for name, level in value.items())
263
+
264
+
265
+ class _StderrthresholdFlag(flags.Flag):
266
+ """Flag class for --stderrthreshold."""
267
+
268
+ def __init__(self, *args, **kwargs):
269
+ super(_StderrthresholdFlag, self).__init__(
270
+ flags.ArgumentParser(),
271
+ flags.ArgumentSerializer(),
272
+ *args, **kwargs)
273
+
274
+ @property
275
+ def value(self):
276
+ return self._value
277
+
278
+ @value.setter
279
+ def value(self, v):
280
+ if v in _CPP_LEVEL_TO_NAMES:
281
+ # --stderrthreshold also accepts numeric strings whose values are
282
+ # Abseil C++ log levels.
283
+ cpp_value = int(v)
284
+ v = _CPP_LEVEL_TO_NAMES[v] # Normalize to strings.
285
+ elif v.lower() in _CPP_NAME_TO_LEVELS:
286
+ v = v.lower()
287
+ if v == 'warn':
288
+ v = 'warning' # Use 'warning' as the canonical name.
289
+ cpp_value = int(_CPP_NAME_TO_LEVELS[v])
290
+ else:
291
+ raise ValueError(
292
+ '--stderrthreshold must be one of (case-insensitive) '
293
+ "'debug', 'info', 'warning', 'error', 'fatal', "
294
+ "or '0', '1', '2', '3', not '%s'" % v)
295
+
296
+ self._value = v
297
+
298
+
299
+ LOGTOSTDERR = flags.DEFINE_boolean(
300
+ 'logtostderr',
301
+ False,
302
+ 'Should only log to stderr?',
303
+ allow_override_cpp=True,
304
+ )
305
+ ALSOLOGTOSTDERR = flags.DEFINE_boolean(
306
+ 'alsologtostderr',
307
+ False,
308
+ 'also log to stderr?',
309
+ allow_override_cpp=True,
310
+ )
311
+ LOG_DIR = flags.DEFINE_string(
312
+ 'log_dir',
313
+ os.getenv('TEST_TMPDIR', ''),
314
+ 'directory to write logfiles into',
315
+ allow_override_cpp=True,
316
+ )
317
+ VERBOSITY = flags.DEFINE_flag(
318
+ _VerbosityFlag(
319
+ 'verbosity',
320
+ -1,
321
+ (
322
+ 'Logging verbosity level. Messages logged at this level or lower'
323
+ ' will be included. Set to 1 for debug logging. If the flag was not'
324
+ ' set or supplied, the value will be changed from the default of -1'
325
+ ' (warning) to 0 (info) after flags are parsed.'
326
+ ),
327
+ short_name='v',
328
+ allow_hide_cpp=True,
329
+ )
330
+ )
331
+ LOGGER_LEVELS = flags.DEFINE_flag(
332
+ _LoggerLevelsFlag(
333
+ 'logger_levels',
334
+ {},
335
+ (
336
+ 'Specify log level of loggers. The format is a CSV list of '
337
+ '`name:level`. Where `name` is the logger name used with '
338
+ '`logging.getLogger()`, and `level` is a level name (INFO, DEBUG, '
339
+ 'etc). e.g. `myapp.foo:INFO,other.logger:DEBUG`'
340
+ ),
341
+ )
342
+ )
343
+ STDERRTHRESHOLD = flags.DEFINE_flag(
344
+ _StderrthresholdFlag(
345
+ 'stderrthreshold',
346
+ 'fatal',
347
+ (
348
+ 'log messages at this level, or more severe, to stderr in '
349
+ 'addition to the logfile. Possible values are '
350
+ "'debug', 'info', 'warning', 'error', and 'fatal'. "
351
+ 'Obsoletes --alsologtostderr. Using --alsologtostderr '
352
+ 'cancels the effect of this flag. Please also note that '
353
+ 'this flag is subject to --verbosity and requires logfile '
354
+ 'not be stderr.'
355
+ ),
356
+ allow_hide_cpp=True,
357
+ )
358
+ )
359
+ SHOWPREFIXFORINFO = flags.DEFINE_boolean(
360
+ 'showprefixforinfo',
361
+ True,
362
+ (
363
+ 'If False, do not prepend prefix to info messages '
364
+ "when it's logged to stderr, "
365
+ '--verbosity is set to INFO level, '
366
+ 'and python logging is used.'
367
+ ),
368
+ )
369
+
370
+
371
+ def get_verbosity():
372
+ """Returns the logging verbosity."""
373
+ return FLAGS['verbosity'].value
374
+
375
+
376
+ def set_verbosity(v):
377
+ """Sets the logging verbosity.
378
+
379
+ Causes all messages of level <= v to be logged,
380
+ and all messages of level > v to be silently discarded.
381
+
382
+ Args:
383
+ v: int|str, the verbosity level as an integer or string. Legal string values
384
+ are those that can be coerced to an integer as well as case-insensitive
385
+ 'debug', 'info', 'warning', 'error', and 'fatal'.
386
+ """
387
+ try:
388
+ new_level = int(v)
389
+ except ValueError:
390
+ new_level = converter.ABSL_NAMES[v.upper()]
391
+ FLAGS.verbosity = new_level
392
+
393
+
394
+ def set_stderrthreshold(s):
395
+ """Sets the stderr threshold to the value passed in.
396
+
397
+ Args:
398
+ s: str|int, valid strings values are case-insensitive 'debug',
399
+ 'info', 'warning', 'error', and 'fatal'; valid integer values are
400
+ logging.DEBUG|INFO|WARNING|ERROR|FATAL.
401
+
402
+ Raises:
403
+ ValueError: Raised when s is an invalid value.
404
+ """
405
+ if s in converter.ABSL_LEVELS:
406
+ FLAGS.stderrthreshold = converter.ABSL_LEVELS[s]
407
+ elif isinstance(s, str) and s.upper() in converter.ABSL_NAMES:
408
+ FLAGS.stderrthreshold = s
409
+ else:
410
+ raise ValueError(
411
+ 'set_stderrthreshold only accepts integer absl logging level '
412
+ 'from -3 to 1, or case-insensitive string values '
413
+ "'debug', 'info', 'warning', 'error', and 'fatal'. "
414
+ 'But found "{}" ({}).'.format(s, type(s)))
415
+
416
+
417
+ def fatal(msg, *args, **kwargs):
418
+ # type: (Any, Any, Any) -> NoReturn
419
+ """Logs a fatal message."""
420
+ log(FATAL, msg, *args, **kwargs)
421
+
422
+
423
+ def error(msg, *args, **kwargs):
424
+ """Logs an error message."""
425
+ log(ERROR, msg, *args, **kwargs)
426
+
427
+
428
+ def warning(msg, *args, **kwargs):
429
+ """Logs a warning message."""
430
+ log(WARNING, msg, *args, **kwargs)
431
+
432
+
433
+ def warn(msg, *args, **kwargs):
434
+ """Deprecated, use 'warning' instead."""
435
+ warnings.warn("The 'warn' function is deprecated, use 'warning' instead",
436
+ DeprecationWarning, 2)
437
+ log(WARNING, msg, *args, **kwargs)
438
+
439
+
440
+ def info(msg, *args, **kwargs):
441
+ """Logs an info message."""
442
+ log(INFO, msg, *args, **kwargs)
443
+
444
+
445
+ def debug(msg, *args, **kwargs):
446
+ """Logs a debug message."""
447
+ log(DEBUG, msg, *args, **kwargs)
448
+
449
+
450
+ def exception(msg, *args, exc_info=True, **kwargs):
451
+ """Logs an exception, with traceback and message."""
452
+ error(msg, *args, exc_info=exc_info, **kwargs)
453
+
454
+
455
+ # Counter to keep track of number of log entries per token.
456
+ _log_counter_per_token = {}
457
+
458
+
459
+ def _get_next_log_count_per_token(token):
460
+ """Wrapper for _log_counter_per_token. Thread-safe.
461
+
462
+ Args:
463
+ token: The token for which to look up the count.
464
+
465
+ Returns:
466
+ The number of times this function has been called with
467
+ *token* as an argument (starting at 0).
468
+ """
469
+ # Can't use a defaultdict because defaultdict isn't atomic, whereas
470
+ # setdefault is.
471
+ return next(_log_counter_per_token.setdefault(token, itertools.count()))
472
+
473
+
474
+ def log_every_n(level, msg, n, *args):
475
+ """Logs ``msg % args`` at level 'level' once per 'n' times.
476
+
477
+ Logs the 1st call, (N+1)st call, (2N+1)st call, etc.
478
+ Not threadsafe.
479
+
480
+ Args:
481
+ level: int, the absl logging level at which to log.
482
+ msg: str, the message to be logged.
483
+ n: int, the number of times this should be called before it is logged.
484
+ *args: The args to be substituted into the msg.
485
+ """
486
+ count = _get_next_log_count_per_token(get_absl_logger().findCaller())
487
+ log_if(level, msg, not (count % n), *args)
488
+
489
+
490
+ # Keeps track of the last log time of the given token.
491
+ # Note: must be a dict since set/get is atomic in CPython.
492
+ # Note: entries are never released as their number is expected to be low.
493
+ _log_timer_per_token = {}
494
+
495
+
496
+ def _seconds_have_elapsed(token, num_seconds):
497
+ """Tests if 'num_seconds' have passed since 'token' was requested.
498
+
499
+ Not strictly thread-safe - may log with the wrong frequency if called
500
+ concurrently from multiple threads. Accuracy depends on resolution of
501
+ 'timeit.default_timer()'.
502
+
503
+ Always returns True on the first call for a given 'token'.
504
+
505
+ Args:
506
+ token: The token for which to look up the count.
507
+ num_seconds: The number of seconds to test for.
508
+
509
+ Returns:
510
+ Whether it has been >= 'num_seconds' since 'token' was last requested.
511
+ """
512
+ now = timeit.default_timer()
513
+ then = _log_timer_per_token.get(token, None)
514
+ if then is None or (now - then) >= num_seconds:
515
+ _log_timer_per_token[token] = now
516
+ return True
517
+ else:
518
+ return False
519
+
520
+
521
+ def log_every_n_seconds(level, msg, n_seconds, *args):
522
+ """Logs ``msg % args`` at level ``level`` iff ``n_seconds`` elapsed since last call.
523
+
524
+ Logs the first call, logs subsequent calls if 'n' seconds have elapsed since
525
+ the last logging call from the same call site (file + line). Not thread-safe.
526
+
527
+ Args:
528
+ level: int, the absl logging level at which to log.
529
+ msg: str, the message to be logged.
530
+ n_seconds: float or int, seconds which should elapse before logging again.
531
+ *args: The args to be substituted into the msg.
532
+ """
533
+ should_log = _seconds_have_elapsed(get_absl_logger().findCaller(), n_seconds)
534
+ log_if(level, msg, should_log, *args)
535
+
536
+
537
+ def log_first_n(level, msg, n, *args):
538
+ """Logs ``msg % args`` at level ``level`` only first ``n`` times.
539
+
540
+ Not threadsafe.
541
+
542
+ Args:
543
+ level: int, the absl logging level at which to log.
544
+ msg: str, the message to be logged.
545
+ n: int, the maximal number of times the message is logged.
546
+ *args: The args to be substituted into the msg.
547
+ """
548
+ count = _get_next_log_count_per_token(get_absl_logger().findCaller())
549
+ log_if(level, msg, count < n, *args)
550
+
551
+
552
+ def log_if(level, msg, condition, *args):
553
+ """Logs ``msg % args`` at level ``level`` only if condition is fulfilled."""
554
+ if condition:
555
+ log(level, msg, *args)
556
+
557
+
558
+ def log(level, msg, *args, **kwargs):
559
+ """Logs ``msg % args`` at absl logging level ``level``.
560
+
561
+ If no args are given just print msg, ignoring any interpolation specifiers.
562
+
563
+ Args:
564
+ level: int, the absl logging level at which to log the message
565
+ (logging.DEBUG|INFO|WARNING|ERROR|FATAL). While some C++ verbose logging
566
+ level constants are also supported, callers should prefer explicit
567
+ logging.vlog() calls for such purpose.
568
+
569
+ msg: str, the message to be logged.
570
+ *args: The args to be substituted into the msg.
571
+ **kwargs: May contain exc_info to add exception traceback to message.
572
+ """
573
+ if level > converter.ABSL_DEBUG:
574
+ # Even though this function supports level that is greater than 1, users
575
+ # should use logging.vlog instead for such cases.
576
+ # Treat this as vlog, 1 is equivalent to DEBUG.
577
+ standard_level = converter.STANDARD_DEBUG - (level - 1)
578
+ else:
579
+ if level < converter.ABSL_FATAL:
580
+ level = converter.ABSL_FATAL
581
+ standard_level = converter.absl_to_standard(level)
582
+
583
+ # Match standard logging's behavior. Before use_absl_handler() and
584
+ # logging is configured, there is no handler attached on _absl_logger nor
585
+ # logging.root. So logs go no where.
586
+ if not logging.root.handlers:
587
+ logging.basicConfig()
588
+
589
+ _absl_logger.log(standard_level, msg, *args, **kwargs)
590
+
591
+
592
+ def vlog(level, msg, *args, **kwargs):
593
+ """Log ``msg % args`` at C++ vlog level ``level``.
594
+
595
+ Args:
596
+ level: int, the C++ verbose logging level at which to log the message,
597
+ e.g. 1, 2, 3, 4... While absl level constants are also supported,
598
+ callers should prefer logging.log|debug|info|... calls for such purpose.
599
+ msg: str, the message to be logged.
600
+ *args: The args to be substituted into the msg.
601
+ **kwargs: May contain exc_info to add exception traceback to message.
602
+ """
603
+ log(level, msg, *args, **kwargs)
604
+
605
+
606
+ def vlog_is_on(level):
607
+ """Checks if vlog is enabled for the given level in caller's source file.
608
+
609
+ Args:
610
+ level: int, the C++ verbose logging level at which to log the message,
611
+ e.g. 1, 2, 3, 4... While absl level constants are also supported,
612
+ callers should prefer level_debug|level_info|... calls for
613
+ checking those.
614
+
615
+ Returns:
616
+ True if logging is turned on for that level.
617
+ """
618
+
619
+ if level > converter.ABSL_DEBUG:
620
+ # Even though this function supports level that is greater than 1, users
621
+ # should use logging.vlog instead for such cases.
622
+ # Treat this as vlog, 1 is equivalent to DEBUG.
623
+ standard_level = converter.STANDARD_DEBUG - (level - 1)
624
+ else:
625
+ if level < converter.ABSL_FATAL:
626
+ level = converter.ABSL_FATAL
627
+ standard_level = converter.absl_to_standard(level)
628
+ return _absl_logger.isEnabledFor(standard_level)
629
+
630
+
631
+ def flush():
632
+ """Flushes all log files."""
633
+ get_absl_handler().flush()
634
+
635
+
636
+ def level_debug():
637
+ """Returns True if debug logging is turned on."""
638
+ return get_verbosity() >= DEBUG
639
+
640
+
641
+ def level_info():
642
+ """Returns True if info logging is turned on."""
643
+ return get_verbosity() >= INFO
644
+
645
+
646
+ def level_warning():
647
+ """Returns True if warning logging is turned on."""
648
+ return get_verbosity() >= WARNING
649
+
650
+
651
+ level_warn = level_warning # Deprecated function.
652
+
653
+
654
+ def level_error():
655
+ """Returns True if error logging is turned on."""
656
+ return get_verbosity() >= ERROR
657
+
658
+
659
+ def get_log_file_name(level=INFO):
660
+ """Returns the name of the log file.
661
+
662
+ For Python logging, only one file is used and level is ignored. And it returns
663
+ empty string if it logs to stderr/stdout or the log stream has no `name`
664
+ attribute.
665
+
666
+ Args:
667
+ level: int, the absl.logging level.
668
+
669
+ Raises:
670
+ ValueError: Raised when `level` has an invalid value.
671
+ """
672
+ if level not in converter.ABSL_LEVELS:
673
+ raise ValueError('Invalid absl.logging level {}'.format(level))
674
+ stream = get_absl_handler().python_handler.stream
675
+ if (stream == sys.stderr or stream == sys.stdout or
676
+ not hasattr(stream, 'name')):
677
+ return ''
678
+ else:
679
+ return stream.name
680
+
681
+
682
+ def find_log_dir_and_names(program_name=None, log_dir=None):
683
+ """Computes the directory and filename prefix for log file.
684
+
685
+ Args:
686
+ program_name: str|None, the filename part of the path to the program that
687
+ is running without its extension. e.g: if your program is called
688
+ ``usr/bin/foobar.py`` this method should probably be called with
689
+ ``program_name='foobar`` However, this is just a convention, you can
690
+ pass in any string you want, and it will be used as part of the
691
+ log filename. If you don't pass in anything, the default behavior
692
+ is as described in the example. In python standard logging mode,
693
+ the program_name will be prepended with ``py_`` if it is the
694
+ ``program_name`` argument is omitted.
695
+ log_dir: str|None, the desired log directory.
696
+
697
+ Returns:
698
+ (log_dir, file_prefix, symlink_prefix)
699
+
700
+ Raises:
701
+ FileNotFoundError: raised in Python 3 when it cannot find a log directory.
702
+ OSError: raised in Python 2 when it cannot find a log directory.
703
+ """
704
+ if not program_name:
705
+ # Strip the extension (foobar.par becomes foobar, and
706
+ # fubar.py becomes fubar). We do this so that the log
707
+ # file names are similar to C++ log file names.
708
+ program_name = os.path.splitext(os.path.basename(sys.argv[0]))[0]
709
+
710
+ # Prepend py_ to files so that python code gets a unique file, and
711
+ # so that C++ libraries do not try to write to the same log files as us.
712
+ program_name = 'py_%s' % program_name
713
+
714
+ actual_log_dir = find_log_dir(log_dir=log_dir)
715
+
716
+ try:
717
+ username = getpass.getuser()
718
+ except KeyError:
719
+ # This can happen, e.g. when running under docker w/o passwd file.
720
+ if hasattr(os, 'getuid'):
721
+ # Windows doesn't have os.getuid
722
+ username = str(os.getuid())
723
+ else:
724
+ username = 'unknown'
725
+ hostname = socket.gethostname()
726
+ file_prefix = '%s.%s.%s.log' % (program_name, hostname, username)
727
+
728
+ return actual_log_dir, file_prefix, program_name
729
+
730
+
731
+ def find_log_dir(log_dir=None):
732
+ """Returns the most suitable directory to put log files into.
733
+
734
+ Args:
735
+ log_dir: str|None, if specified, the logfile(s) will be created in that
736
+ directory. Otherwise if the --log_dir command-line flag is provided,
737
+ the logfile will be created in that directory. Otherwise the logfile
738
+ will be created in a standard location.
739
+
740
+ Raises:
741
+ FileNotFoundError: raised in Python 3 when it cannot find a log directory.
742
+ OSError: raised in Python 2 when it cannot find a log directory.
743
+ """
744
+ # Get a list of possible log dirs (will try to use them in order).
745
+ # NOTE: Google's internal implementation has a special handling for Google
746
+ # machines, which uses a list of directories. Hence the following uses `dirs`
747
+ # instead of a single directory.
748
+ if log_dir:
749
+ # log_dir was explicitly specified as an arg, so use it and it alone.
750
+ dirs = [log_dir]
751
+ elif FLAGS['log_dir'].value:
752
+ # log_dir flag was provided, so use it and it alone (this mimics the
753
+ # behavior of the same flag in logging.cc).
754
+ dirs = [FLAGS['log_dir'].value]
755
+ else:
756
+ dirs = [tempfile.gettempdir()]
757
+
758
+ # Find the first usable log dir.
759
+ for d in dirs:
760
+ if os.path.isdir(d) and os.access(d, os.W_OK):
761
+ return d
762
+ raise FileNotFoundError(
763
+ "Can't find a writable directory for logs, tried %s" % dirs)
764
+
765
+
766
+ def get_absl_log_prefix(record):
767
+ """Returns the absl log prefix for the log record.
768
+
769
+ Args:
770
+ record: logging.LogRecord, the record to get prefix for.
771
+ """
772
+ created_tuple = time.localtime(record.created)
773
+ created_microsecond = int(record.created % 1.0 * 1e6)
774
+
775
+ critical_prefix = ''
776
+ level = record.levelno
777
+ if _is_non_absl_fatal_record(record):
778
+ # When the level is FATAL, but not logged from absl, lower the level so
779
+ # it's treated as ERROR.
780
+ level = logging.ERROR
781
+ critical_prefix = _CRITICAL_PREFIX
782
+ severity = converter.get_initial_for_level(level)
783
+
784
+ return '%c%02d%02d %02d:%02d:%02d.%06d %5d %s:%d] %s' % (
785
+ severity,
786
+ created_tuple.tm_mon,
787
+ created_tuple.tm_mday,
788
+ created_tuple.tm_hour,
789
+ created_tuple.tm_min,
790
+ created_tuple.tm_sec,
791
+ created_microsecond,
792
+ _get_thread_id(),
793
+ record.filename,
794
+ record.lineno,
795
+ critical_prefix)
796
+
797
+
798
+ def skip_log_prefix(func):
799
+ """Skips reporting the prefix of a given function or name by :class:`~absl.logging.ABSLLogger`.
800
+
801
+ This is a convenience wrapper function / decorator for
802
+ :meth:`~absl.logging.ABSLLogger.register_frame_to_skip`.
803
+
804
+ If a callable function is provided, only that function will be skipped.
805
+ If a function name is provided, all functions with the same name in the
806
+ file that this is called in will be skipped.
807
+
808
+ This can be used as a decorator of the intended function to be skipped.
809
+
810
+ Args:
811
+ func: Callable function or its name as a string.
812
+
813
+ Returns:
814
+ func (the input, unchanged).
815
+
816
+ Raises:
817
+ ValueError: The input is callable but does not have a function code object.
818
+ TypeError: The input is neither callable nor a string.
819
+ """
820
+ if callable(func):
821
+ func_code = getattr(func, '__code__', None)
822
+ if func_code is None:
823
+ raise ValueError('Input callable does not have a function code object.')
824
+ file_name = func_code.co_filename
825
+ func_name = func_code.co_name
826
+ func_lineno = func_code.co_firstlineno
827
+ elif isinstance(func, str):
828
+ file_name = get_absl_logger().findCaller()[0]
829
+ func_name = func
830
+ func_lineno = None
831
+ else:
832
+ raise TypeError('Input is neither callable nor a string.')
833
+ ABSLLogger.register_frame_to_skip(file_name, func_name, func_lineno)
834
+ return func
835
+
836
+
837
+ def _is_non_absl_fatal_record(log_record):
838
+ return (log_record.levelno >= logging.FATAL and
839
+ not log_record.__dict__.get(_ABSL_LOG_FATAL, False))
840
+
841
+
842
+ def _is_absl_fatal_record(log_record):
843
+ return (log_record.levelno >= logging.FATAL and
844
+ log_record.__dict__.get(_ABSL_LOG_FATAL, False))
845
+
846
+
847
+ # Indicates if we still need to warn about pre-init logs going to stderr.
848
+ _warn_preinit_stderr = True
849
+
850
+
851
+ class PythonHandler(logging.StreamHandler):
852
+ """The handler class used by Abseil Python logging implementation."""
853
+
854
+ def __init__(self, stream=None, formatter=None):
855
+ super(PythonHandler, self).__init__(stream)
856
+ self.setFormatter(formatter or PythonFormatter())
857
+
858
+ def start_logging_to_file(self, program_name=None, log_dir=None):
859
+ """Starts logging messages to files instead of standard error."""
860
+ FLAGS.logtostderr = False
861
+
862
+ actual_log_dir, file_prefix, symlink_prefix = find_log_dir_and_names(
863
+ program_name=program_name, log_dir=log_dir)
864
+
865
+ basename = '%s.INFO.%s.%d' % (
866
+ file_prefix,
867
+ time.strftime('%Y%m%d-%H%M%S', time.localtime(time.time())),
868
+ os.getpid())
869
+ filename = os.path.join(actual_log_dir, basename)
870
+
871
+ self.stream = open(filename, 'a', encoding='utf-8')
872
+
873
+ # os.symlink is not available on Windows Python 2.
874
+ if getattr(os, 'symlink', None):
875
+ # Create a symlink to the log file with a canonical name.
876
+ symlink = os.path.join(actual_log_dir, symlink_prefix + '.INFO')
877
+ try:
878
+ if os.path.islink(symlink):
879
+ os.unlink(symlink)
880
+ os.symlink(os.path.basename(filename), symlink)
881
+ except EnvironmentError:
882
+ # If it fails, we're sad but it's no error. Commonly, this
883
+ # fails because the symlink was created by another user and so
884
+ # we can't modify it
885
+ pass
886
+
887
+ def use_absl_log_file(self, program_name=None, log_dir=None):
888
+ """Conditionally logs to files, based on --logtostderr."""
889
+ if FLAGS['logtostderr'].value:
890
+ self.stream = sys.stderr
891
+ else:
892
+ self.start_logging_to_file(program_name=program_name, log_dir=log_dir)
893
+
894
+ def flush(self):
895
+ """Flushes all log files."""
896
+ self.acquire()
897
+ try:
898
+ if self.stream and hasattr(self.stream, 'flush'):
899
+ self.stream.flush()
900
+ except (EnvironmentError, ValueError):
901
+ # A ValueError is thrown if we try to flush a closed file.
902
+ pass
903
+ finally:
904
+ self.release()
905
+
906
+ def _log_to_stderr(self, record):
907
+ """Emits the record to stderr.
908
+
909
+ This temporarily sets the handler stream to stderr, calls
910
+ StreamHandler.emit, then reverts the stream back.
911
+
912
+ Args:
913
+ record: logging.LogRecord, the record to log.
914
+ """
915
+ # emit() is protected by a lock in logging.Handler, so we don't need to
916
+ # protect here again.
917
+ old_stream = self.stream
918
+ self.stream = sys.stderr
919
+ try:
920
+ super(PythonHandler, self).emit(record)
921
+ finally:
922
+ self.stream = old_stream
923
+
924
+ def emit(self, record):
925
+ """Prints a record out to some streams.
926
+
927
+ 1. If ``FLAGS.logtostderr`` is set, it will print to ``sys.stderr`` ONLY.
928
+ 2. If ``FLAGS.alsologtostderr`` is set, it will print to ``sys.stderr``.
929
+ 3. If ``FLAGS.logtostderr`` is not set, it will log to the stream
930
+ associated with the current thread.
931
+
932
+ Args:
933
+ record: :class:`logging.LogRecord`, the record to emit.
934
+ """
935
+ # People occasionally call logging functions at import time before
936
+ # our flags may have even been defined yet, let alone even parsed, as we
937
+ # rely on the C++ side to define some flags for us and app init to
938
+ # deal with parsing. Match the C++ library behavior of notify and emit
939
+ # such messages to stderr. It encourages people to clean-up and does
940
+ # not hide the message.
941
+ level = record.levelno
942
+ if not FLAGS.is_parsed(): # Also implies "before flag has been defined".
943
+ global _warn_preinit_stderr
944
+ if _warn_preinit_stderr:
945
+ sys.stderr.write(
946
+ 'WARNING: Logging before flag parsing goes to stderr.\n')
947
+ _warn_preinit_stderr = False
948
+ self._log_to_stderr(record)
949
+ elif FLAGS['logtostderr'].value:
950
+ self._log_to_stderr(record)
951
+ else:
952
+ super(PythonHandler, self).emit(record)
953
+ stderr_threshold = converter.string_to_standard(
954
+ FLAGS['stderrthreshold'].value)
955
+ if ((FLAGS['alsologtostderr'].value or level >= stderr_threshold) and
956
+ self.stream != sys.stderr):
957
+ self._log_to_stderr(record)
958
+ # Die when the record is created from ABSLLogger and level is FATAL.
959
+ if _is_absl_fatal_record(record):
960
+ self.flush() # Flush the log before dying.
961
+
962
+ # In threaded python, sys.exit() from a non-main thread only
963
+ # exits the thread in question.
964
+ os.abort()
965
+
966
+ def close(self):
967
+ """Closes the stream to which we are writing."""
968
+ self.acquire()
969
+ try:
970
+ self.flush()
971
+ try:
972
+ # Do not close the stream if it's sys.stderr|stdout. They may be
973
+ # redirected or overridden to files, which should be managed by users
974
+ # explicitly.
975
+ user_managed = sys.stderr, sys.stdout, sys.__stderr__, sys.__stdout__
976
+ if self.stream not in user_managed and (
977
+ not hasattr(self.stream, 'isatty') or not self.stream.isatty()):
978
+ self.stream.close()
979
+ except ValueError:
980
+ # A ValueError is thrown if we try to run isatty() on a closed file.
981
+ pass
982
+ super(PythonHandler, self).close()
983
+ finally:
984
+ self.release()
985
+
986
+
987
+ class ABSLHandler(logging.Handler):
988
+ """Abseil Python logging module's log handler."""
989
+
990
+ def __init__(self, python_logging_formatter):
991
+ super(ABSLHandler, self).__init__()
992
+
993
+ self._python_handler = PythonHandler(formatter=python_logging_formatter)
994
+ self.activate_python_handler()
995
+
996
+ def format(self, record):
997
+ return self._current_handler.format(record)
998
+
999
+ def setFormatter(self, fmt):
1000
+ self._current_handler.setFormatter(fmt)
1001
+
1002
+ def emit(self, record):
1003
+ self._current_handler.emit(record)
1004
+
1005
+ def flush(self):
1006
+ self._current_handler.flush()
1007
+
1008
+ def close(self):
1009
+ super(ABSLHandler, self).close()
1010
+ self._current_handler.close()
1011
+
1012
+ def handle(self, record):
1013
+ rv = self.filter(record)
1014
+ if rv:
1015
+ return self._current_handler.handle(record)
1016
+ return rv
1017
+
1018
+ @property
1019
+ def python_handler(self):
1020
+ return self._python_handler
1021
+
1022
+ def activate_python_handler(self):
1023
+ """Uses the Python logging handler as the current logging handler."""
1024
+ self._current_handler = self._python_handler
1025
+
1026
+ def use_absl_log_file(self, program_name=None, log_dir=None):
1027
+ self._current_handler.use_absl_log_file(program_name, log_dir)
1028
+
1029
+ def start_logging_to_file(self, program_name=None, log_dir=None):
1030
+ self._current_handler.start_logging_to_file(program_name, log_dir)
1031
+
1032
+
1033
+ class PythonFormatter(logging.Formatter):
1034
+ """Formatter class used by :class:`~absl.logging.PythonHandler`."""
1035
+
1036
+ def format(self, record):
1037
+ """Appends the message from the record to the results of the prefix.
1038
+
1039
+ Args:
1040
+ record: logging.LogRecord, the record to be formatted.
1041
+
1042
+ Returns:
1043
+ The formatted string representing the record.
1044
+ """
1045
+ if (not FLAGS['showprefixforinfo'].value and
1046
+ FLAGS['verbosity'].value == converter.ABSL_INFO and
1047
+ record.levelno == logging.INFO and
1048
+ _absl_handler.python_handler.stream == sys.stderr):
1049
+ prefix = ''
1050
+ else:
1051
+ prefix = get_absl_log_prefix(record)
1052
+ return prefix + super(PythonFormatter, self).format(record)
1053
+
1054
+
1055
+ class ABSLLogger(logging.getLoggerClass()):
1056
+ """A logger that will create LogRecords while skipping some stack frames.
1057
+
1058
+ This class maintains an internal list of filenames and method names
1059
+ for use when determining who called the currently executing stack
1060
+ frame. Any method names from specific source files are skipped when
1061
+ walking backwards through the stack.
1062
+
1063
+ Client code should use the register_frame_to_skip method to let the
1064
+ ABSLLogger know which method from which file should be
1065
+ excluded from the walk backwards through the stack.
1066
+ """
1067
+ _frames_to_skip = set()
1068
+
1069
+ def findCaller(self, stack_info=False, stacklevel=1):
1070
+ """Finds the frame of the calling method on the stack.
1071
+
1072
+ This method skips any frames registered with the
1073
+ ABSLLogger and any methods from this file, and whatever
1074
+ method is currently being used to generate the prefix for the log
1075
+ line. Then it returns the file name, line number, and method name
1076
+ of the calling method. An optional fourth item may be returned,
1077
+ callers who only need things from the first three are advised to
1078
+ always slice or index the result rather than using direct unpacking
1079
+ assignment.
1080
+
1081
+ Args:
1082
+ stack_info: bool, when True, include the stack trace as a fourth item
1083
+ returned. On Python 3 there are always four items returned - the
1084
+ fourth will be None when this is False. On Python 2 the stdlib
1085
+ base class API only returns three items. We do the same when this
1086
+ new parameter is unspecified or False for compatibility.
1087
+
1088
+ Returns:
1089
+ (filename, lineno, methodname[, sinfo]) of the calling method.
1090
+ """
1091
+ f_to_skip = ABSLLogger._frames_to_skip
1092
+ # Use sys._getframe(2) instead of logging.currentframe(), it's slightly
1093
+ # faster because there is one less frame to traverse.
1094
+ frame = sys._getframe(2) # pylint: disable=protected-access
1095
+
1096
+ while frame:
1097
+ code = frame.f_code
1098
+ if (_LOGGING_FILE_PREFIX not in code.co_filename and
1099
+ (code.co_filename, code.co_name,
1100
+ code.co_firstlineno) not in f_to_skip and
1101
+ (code.co_filename, code.co_name) not in f_to_skip):
1102
+ sinfo = None
1103
+ if stack_info:
1104
+ out = io.StringIO()
1105
+ out.write(u'Stack (most recent call last):\n')
1106
+ traceback.print_stack(frame, file=out)
1107
+ sinfo = out.getvalue().rstrip(u'\n')
1108
+ return (code.co_filename, frame.f_lineno, code.co_name, sinfo)
1109
+ frame = frame.f_back
1110
+
1111
+ def critical(self, msg, *args, **kwargs):
1112
+ """Logs ``msg % args`` with severity ``CRITICAL``."""
1113
+ self.log(logging.CRITICAL, msg, *args, **kwargs)
1114
+
1115
+ def fatal(self, msg, *args, **kwargs):
1116
+ """Logs ``msg % args`` with severity ``FATAL``."""
1117
+ self.log(logging.FATAL, msg, *args, **kwargs)
1118
+
1119
+ def error(self, msg, *args, **kwargs):
1120
+ """Logs ``msg % args`` with severity ``ERROR``."""
1121
+ self.log(logging.ERROR, msg, *args, **kwargs)
1122
+
1123
+ def warn(self, msg, *args, **kwargs):
1124
+ """Logs ``msg % args`` with severity ``WARN``."""
1125
+ warnings.warn("The 'warn' method is deprecated, use 'warning' instead",
1126
+ DeprecationWarning, 2)
1127
+ self.log(logging.WARN, msg, *args, **kwargs)
1128
+
1129
+ def warning(self, msg, *args, **kwargs):
1130
+ """Logs ``msg % args`` with severity ``WARNING``."""
1131
+ self.log(logging.WARNING, msg, *args, **kwargs)
1132
+
1133
+ def info(self, msg, *args, **kwargs):
1134
+ """Logs ``msg % args`` with severity ``INFO``."""
1135
+ self.log(logging.INFO, msg, *args, **kwargs)
1136
+
1137
+ def debug(self, msg, *args, **kwargs):
1138
+ """Logs ``msg % args`` with severity ``DEBUG``."""
1139
+ self.log(logging.DEBUG, msg, *args, **kwargs)
1140
+
1141
+ def log(self, level, msg, *args, **kwargs):
1142
+ """Logs a message at a cetain level substituting in the supplied arguments.
1143
+
1144
+ This method behaves differently in python and c++ modes.
1145
+
1146
+ Args:
1147
+ level: int, the standard logging level at which to log the message.
1148
+ msg: str, the text of the message to log.
1149
+ *args: The arguments to substitute in the message.
1150
+ **kwargs: The keyword arguments to substitute in the message.
1151
+ """
1152
+ if level >= logging.FATAL:
1153
+ # Add property to the LogRecord created by this logger.
1154
+ # This will be used by the ABSLHandler to determine whether it should
1155
+ # treat CRITICAL/FATAL logs as really FATAL.
1156
+ extra = kwargs.setdefault('extra', {})
1157
+ extra[_ABSL_LOG_FATAL] = True
1158
+ super(ABSLLogger, self).log(level, msg, *args, **kwargs)
1159
+
1160
+ def handle(self, record):
1161
+ """Calls handlers without checking ``Logger.disabled``.
1162
+
1163
+ Non-root loggers are set to disabled after setup with :func:`logging.config`
1164
+ if it's not explicitly specified. Historically, absl logging will not be
1165
+ disabled by that. To maintaining this behavior, this function skips
1166
+ checking the ``Logger.disabled`` bit.
1167
+
1168
+ This logger can still be disabled by adding a filter that filters out
1169
+ everything.
1170
+
1171
+ Args:
1172
+ record: logging.LogRecord, the record to handle.
1173
+ """
1174
+ if self.filter(record):
1175
+ self.callHandlers(record)
1176
+
1177
+ @classmethod
1178
+ def register_frame_to_skip(cls, file_name, function_name, line_number=None):
1179
+ """Registers a function name to skip when walking the stack.
1180
+
1181
+ The :class:`~absl.logging.ABSLLogger` sometimes skips method calls on the
1182
+ stack to make the log messages meaningful in their appropriate context.
1183
+ This method registers a function from a particular file as one
1184
+ which should be skipped.
1185
+
1186
+ Args:
1187
+ file_name: str, the name of the file that contains the function.
1188
+ function_name: str, the name of the function to skip.
1189
+ line_number: int, if provided, only the function with this starting line
1190
+ number will be skipped. Otherwise, all functions with the same name
1191
+ in the file will be skipped.
1192
+ """
1193
+ if line_number is not None:
1194
+ cls._frames_to_skip.add((file_name, function_name, line_number))
1195
+ else:
1196
+ cls._frames_to_skip.add((file_name, function_name))
1197
+
1198
+
1199
+ def _get_thread_id():
1200
+ """Gets id of current thread, suitable for logging as an unsigned quantity.
1201
+
1202
+ If pywrapbase is linked, returns GetTID() for the thread ID to be
1203
+ consistent with C++ logging. Otherwise, returns the numeric thread id.
1204
+ The quantities are made unsigned by masking with 2*sys.maxint + 1.
1205
+
1206
+ Returns:
1207
+ Thread ID unique to this process (unsigned)
1208
+ """
1209
+ thread_id = threading.get_ident()
1210
+ return thread_id & _THREAD_ID_MASK
1211
+
1212
+
1213
+ def get_absl_logger():
1214
+ """Returns the absl logger instance."""
1215
+ assert _absl_logger is not None
1216
+ return _absl_logger
1217
+
1218
+
1219
+ def get_absl_handler():
1220
+ """Returns the absl handler instance."""
1221
+ assert _absl_handler is not None
1222
+ return _absl_handler
1223
+
1224
+
1225
+ def use_python_logging(quiet=False):
1226
+ """Uses the python implementation of the logging code.
1227
+
1228
+ Args:
1229
+ quiet: No logging message about switching logging type.
1230
+ """
1231
+ get_absl_handler().activate_python_handler()
1232
+ if not quiet:
1233
+ info('Restoring pure python logging')
1234
+
1235
+
1236
+ _attempted_to_remove_stderr_stream_handlers = False
1237
+
1238
+
1239
+ def use_absl_handler():
1240
+ """Uses the ABSL logging handler for logging.
1241
+
1242
+ This method is called in :func:`app.run()<absl.app.run>` so the absl handler
1243
+ is used in absl apps.
1244
+ """
1245
+ global _attempted_to_remove_stderr_stream_handlers
1246
+ if not _attempted_to_remove_stderr_stream_handlers:
1247
+ # The absl handler logs to stderr by default. To prevent double logging to
1248
+ # stderr, the following code tries its best to remove other handlers that
1249
+ # emit to stderr. Those handlers are most commonly added when
1250
+ # logging.info/debug is called before calling use_absl_handler().
1251
+ handlers = [
1252
+ h for h in logging.root.handlers
1253
+ if isinstance(h, logging.StreamHandler) and h.stream == sys.stderr]
1254
+ for h in handlers:
1255
+ logging.root.removeHandler(h)
1256
+ _attempted_to_remove_stderr_stream_handlers = True
1257
+
1258
+ absl_handler = get_absl_handler()
1259
+ if absl_handler not in logging.root.handlers:
1260
+ logging.root.addHandler(absl_handler)
1261
+ FLAGS['verbosity']._update_logging_levels() # pylint: disable=protected-access
1262
+ FLAGS['logger_levels']._update_logger_levels() # pylint: disable=protected-access
1263
+
1264
+
1265
+ def _initialize():
1266
+ """Initializes loggers and handlers."""
1267
+ global _absl_logger, _absl_handler
1268
+
1269
+ if _absl_logger:
1270
+ return
1271
+
1272
+ original_logger_class = logging.getLoggerClass()
1273
+ logging.setLoggerClass(ABSLLogger)
1274
+ _absl_logger = logging.getLogger('absl')
1275
+ logging.setLoggerClass(original_logger_class)
1276
+
1277
+ python_logging_formatter = PythonFormatter()
1278
+ _absl_handler = ABSLHandler(python_logging_formatter)
1279
+
1280
+
1281
+ _initialize()
MLPY/Lib/site-packages/absl/logging/__init__.pyi ADDED
@@ -0,0 +1,290 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2017 The Abseil Authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import logging
16
+ from typing import Any, Callable, Dict, NoReturn, Optional, Tuple, TypeVar, Union
17
+
18
+ from absl import flags
19
+
20
+ # Logging levels.
21
+ FATAL: int
22
+ ERROR: int
23
+ WARNING: int
24
+ WARN: int # Deprecated name.
25
+ INFO: int
26
+ DEBUG: int
27
+
28
+ ABSL_LOGGING_PREFIX_REGEX: str
29
+
30
+ LOGTOSTDERR: flags.FlagHolder[bool]
31
+ ALSOLOGTOSTDERR: flags.FlagHolder[bool]
32
+ LOG_DIR: flags.FlagHolder[str]
33
+ VERBOSITY: flags.FlagHolder[int]
34
+ LOGGER_LEVELS: flags.FlagHolder[Dict[str, str]]
35
+ STDERRTHRESHOLD: flags.FlagHolder[str]
36
+ SHOWPREFIXFORINFO: flags.FlagHolder[bool]
37
+
38
+
39
+ def get_verbosity() -> int:
40
+ ...
41
+
42
+
43
+ def set_verbosity(v: Union[int, str]) -> None:
44
+ ...
45
+
46
+
47
+ def set_stderrthreshold(s: Union[int, str]) -> None:
48
+ ...
49
+
50
+
51
+ # TODO(b/277607978): Provide actual args+kwargs shadowing stdlib's logging functions.
52
+ def fatal(msg: Any, *args: Any, **kwargs: Any) -> NoReturn:
53
+ ...
54
+
55
+
56
+ def error(msg: Any, *args: Any, **kwargs: Any) -> None:
57
+ ...
58
+
59
+
60
+ def warning(msg: Any, *args: Any, **kwargs: Any) -> None:
61
+ ...
62
+
63
+
64
+ def warn(msg: Any, *args: Any, **kwargs: Any) -> None:
65
+ ...
66
+
67
+
68
+ def info(msg: Any, *args: Any, **kwargs: Any) -> None:
69
+ ...
70
+
71
+
72
+ def debug(msg: Any, *args: Any, **kwargs: Any) -> None:
73
+ ...
74
+
75
+
76
+ def exception(msg: Any, *args: Any, **kwargs: Any) -> None:
77
+ ...
78
+
79
+
80
+ def log_every_n(level: int, msg: Any, n: int, *args: Any) -> None:
81
+ ...
82
+
83
+
84
+ def log_every_n_seconds(
85
+ level: int, msg: Any, n_seconds: float, *args: Any
86
+ ) -> None:
87
+ ...
88
+
89
+
90
+ def log_first_n(level: int, msg: Any, n: int, *args: Any) -> None:
91
+ ...
92
+
93
+
94
+ def log_if(level: int, msg: Any, condition: Any, *args: Any) -> None:
95
+ ...
96
+
97
+
98
+ def log(level: int, msg: Any, *args: Any, **kwargs: Any) -> None:
99
+ ...
100
+
101
+
102
+ def vlog(level: int, msg: Any, *args: Any, **kwargs: Any) -> None:
103
+ ...
104
+
105
+
106
+ def vlog_is_on(level: int) -> bool:
107
+ ...
108
+
109
+
110
+ def flush() -> None:
111
+ ...
112
+
113
+
114
+ def level_debug() -> bool:
115
+ ...
116
+
117
+
118
+ def level_info() -> bool:
119
+ ...
120
+
121
+
122
+ def level_warning() -> bool:
123
+ ...
124
+
125
+
126
+ level_warn = level_warning # Deprecated function.
127
+
128
+
129
+ def level_error() -> bool:
130
+ ...
131
+
132
+
133
+ def get_log_file_name(level: int = ...) -> str:
134
+ ...
135
+
136
+
137
+ def find_log_dir_and_names(
138
+ program_name: Optional[str] = ..., log_dir: Optional[str] = ...
139
+ ) -> Tuple[str, str, str]:
140
+ ...
141
+
142
+
143
+ def find_log_dir(log_dir: Optional[str] = ...) -> str:
144
+ ...
145
+
146
+
147
+ def get_absl_log_prefix(record: logging.LogRecord) -> str:
148
+ ...
149
+
150
+
151
+ _SkipLogT = TypeVar('_SkipLogT', str, Callable[..., Any])
152
+
153
+ def skip_log_prefix(func: _SkipLogT) -> _SkipLogT:
154
+ ...
155
+
156
+
157
+ _StreamT = TypeVar("_StreamT")
158
+
159
+
160
+ class PythonHandler(logging.StreamHandler[_StreamT]):
161
+
162
+ def __init__(
163
+ self,
164
+ stream: Optional[_StreamT] = ...,
165
+ formatter: Optional[logging.Formatter] = ...,
166
+ ) -> None:
167
+ ...
168
+
169
+ def start_logging_to_file(
170
+ self, program_name: Optional[str] = ..., log_dir: Optional[str] = ...
171
+ ) -> None:
172
+ ...
173
+
174
+ def use_absl_log_file(
175
+ self, program_name: Optional[str] = ..., log_dir: Optional[str] = ...
176
+ ) -> None:
177
+ ...
178
+
179
+ def flush(self) -> None:
180
+ ...
181
+
182
+ def emit(self, record: logging.LogRecord) -> None:
183
+ ...
184
+
185
+ def close(self) -> None:
186
+ ...
187
+
188
+
189
+ class ABSLHandler(logging.Handler):
190
+
191
+ def __init__(self, python_logging_formatter: PythonFormatter) -> None:
192
+ ...
193
+
194
+ def format(self, record: logging.LogRecord) -> str:
195
+ ...
196
+
197
+ def setFormatter(self, fmt) -> None:
198
+ ...
199
+
200
+ def emit(self, record: logging.LogRecord) -> None:
201
+ ...
202
+
203
+ def flush(self) -> None:
204
+ ...
205
+
206
+ def close(self) -> None:
207
+ ...
208
+
209
+ def handle(self, record: logging.LogRecord) -> bool:
210
+ ...
211
+
212
+ @property
213
+ def python_handler(self) -> PythonHandler:
214
+ ...
215
+
216
+ def activate_python_handler(self) -> None:
217
+ ...
218
+
219
+ def use_absl_log_file(
220
+ self, program_name: Optional[str] = ..., log_dir: Optional[str] = ...
221
+ ) -> None:
222
+ ...
223
+
224
+ def start_logging_to_file(self, program_name=None, log_dir=None) -> None:
225
+ ...
226
+
227
+
228
+ class PythonFormatter(logging.Formatter):
229
+
230
+ def format(self, record: logging.LogRecord) -> str:
231
+ ...
232
+
233
+
234
+ class ABSLLogger(logging.Logger):
235
+
236
+ def findCaller(
237
+ self, stack_info: bool = ..., stacklevel: int = ...
238
+ ) -> Tuple[str, int, str, Optional[str]]:
239
+ ...
240
+
241
+ def critical(self, msg: Any, *args: Any, **kwargs: Any) -> None:
242
+ ...
243
+
244
+ def fatal(self, msg: Any, *args: Any, **kwargs: Any) -> NoReturn:
245
+ ...
246
+
247
+ def error(self, msg: Any, *args: Any, **kwargs: Any) -> None:
248
+ ...
249
+
250
+ def warn(self, msg: Any, *args: Any, **kwargs: Any) -> None:
251
+ ...
252
+
253
+ def warning(self, msg: Any, *args: Any, **kwargs: Any) -> None:
254
+ ...
255
+
256
+ def info(self, msg: Any, *args: Any, **kwargs: Any) -> None:
257
+ ...
258
+
259
+ def debug(self, msg: Any, *args: Any, **kwargs: Any) -> None:
260
+ ...
261
+
262
+ def log(self, level: int, msg: Any, *args: Any, **kwargs: Any) -> None:
263
+ ...
264
+
265
+ def handle(self, record: logging.LogRecord) -> None:
266
+ ...
267
+
268
+ @classmethod
269
+ def register_frame_to_skip(
270
+ cls, file_name: str, function_name: str, line_number: Optional[int] = ...
271
+ ) -> None:
272
+ ...
273
+
274
+
275
+ # NOTE: Returns None before _initialize called but shouldn't occur after import.
276
+ def get_absl_logger() -> ABSLLogger:
277
+ ...
278
+
279
+
280
+ # NOTE: Returns None before _initialize called but shouldn't occur after import.
281
+ def get_absl_handler() -> ABSLHandler:
282
+ ...
283
+
284
+
285
+ def use_python_logging(quiet: bool = ...) -> None:
286
+ ...
287
+
288
+
289
+ def use_absl_handler() -> None:
290
+ ...
MLPY/Lib/site-packages/absl/logging/__pycache__/__init__.cpython-39.pyc ADDED
Binary file (38.3 kB). View file
 
MLPY/Lib/site-packages/absl/logging/__pycache__/converter.cpython-39.pyc ADDED
Binary file (5.24 kB). View file
 
MLPY/Lib/site-packages/absl/logging/converter.py ADDED
@@ -0,0 +1,214 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2017 The Abseil Authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Module to convert log levels between Abseil Python, C++, and Python standard.
16
+
17
+ This converter has to convert (best effort) between three different
18
+ logging level schemes:
19
+
20
+ * **cpp**: The C++ logging level scheme used in Abseil C++.
21
+ * **absl**: The absl.logging level scheme used in Abseil Python.
22
+ * **standard**: The python standard library logging level scheme.
23
+
24
+ Here is a handy ascii chart for easy mental mapping::
25
+
26
+ LEVEL | cpp | absl | standard |
27
+ ---------+-----+--------+----------+
28
+ DEBUG | 0 | 1 | 10 |
29
+ INFO | 0 | 0 | 20 |
30
+ WARNING | 1 | -1 | 30 |
31
+ ERROR | 2 | -2 | 40 |
32
+ CRITICAL | 3 | -3 | 50 |
33
+ FATAL | 3 | -3 | 50 |
34
+
35
+ Note: standard logging ``CRITICAL`` is mapped to absl/cpp ``FATAL``.
36
+ However, only ``CRITICAL`` logs from the absl logger (or absl.logging.fatal)
37
+ will terminate the program. ``CRITICAL`` logs from non-absl loggers are treated
38
+ as error logs with a message prefix ``"CRITICAL - "``.
39
+
40
+ Converting from standard to absl or cpp is a lossy conversion.
41
+ Converting back to standard will lose granularity. For this reason,
42
+ users should always try to convert to standard, the richest
43
+ representation, before manipulating the levels, and then only to cpp
44
+ or absl if those level schemes are absolutely necessary.
45
+ """
46
+
47
+ import logging
48
+
49
+ STANDARD_CRITICAL = logging.CRITICAL
50
+ STANDARD_ERROR = logging.ERROR
51
+ STANDARD_WARNING = logging.WARNING
52
+ STANDARD_INFO = logging.INFO
53
+ STANDARD_DEBUG = logging.DEBUG
54
+
55
+ # These levels are also used to define the constants
56
+ # FATAL, ERROR, WARNING, INFO, and DEBUG in the
57
+ # absl.logging module.
58
+ ABSL_FATAL = -3
59
+ ABSL_ERROR = -2
60
+ ABSL_WARNING = -1
61
+ ABSL_WARN = -1 # Deprecated name.
62
+ ABSL_INFO = 0
63
+ ABSL_DEBUG = 1
64
+
65
+ ABSL_LEVELS = {ABSL_FATAL: 'FATAL',
66
+ ABSL_ERROR: 'ERROR',
67
+ ABSL_WARNING: 'WARNING',
68
+ ABSL_INFO: 'INFO',
69
+ ABSL_DEBUG: 'DEBUG'}
70
+
71
+ # Inverts the ABSL_LEVELS dictionary
72
+ ABSL_NAMES = {'FATAL': ABSL_FATAL,
73
+ 'ERROR': ABSL_ERROR,
74
+ 'WARNING': ABSL_WARNING,
75
+ 'WARN': ABSL_WARNING, # Deprecated name.
76
+ 'INFO': ABSL_INFO,
77
+ 'DEBUG': ABSL_DEBUG}
78
+
79
+ ABSL_TO_STANDARD = {ABSL_FATAL: STANDARD_CRITICAL,
80
+ ABSL_ERROR: STANDARD_ERROR,
81
+ ABSL_WARNING: STANDARD_WARNING,
82
+ ABSL_INFO: STANDARD_INFO,
83
+ ABSL_DEBUG: STANDARD_DEBUG}
84
+
85
+ # Inverts the ABSL_TO_STANDARD
86
+ STANDARD_TO_ABSL = dict((v, k) for (k, v) in ABSL_TO_STANDARD.items())
87
+
88
+
89
+ def get_initial_for_level(level):
90
+ """Gets the initial that should start the log line for the given level.
91
+
92
+ It returns:
93
+
94
+ * ``'I'`` when: ``level < STANDARD_WARNING``.
95
+ * ``'W'`` when: ``STANDARD_WARNING <= level < STANDARD_ERROR``.
96
+ * ``'E'`` when: ``STANDARD_ERROR <= level < STANDARD_CRITICAL``.
97
+ * ``'F'`` when: ``level >= STANDARD_CRITICAL``.
98
+
99
+ Args:
100
+ level: int, a Python standard logging level.
101
+
102
+ Returns:
103
+ The first initial as it would be logged by the C++ logging module.
104
+ """
105
+ if level < STANDARD_WARNING:
106
+ return 'I'
107
+ elif level < STANDARD_ERROR:
108
+ return 'W'
109
+ elif level < STANDARD_CRITICAL:
110
+ return 'E'
111
+ else:
112
+ return 'F'
113
+
114
+
115
+ def absl_to_cpp(level):
116
+ """Converts an absl log level to a cpp log level.
117
+
118
+ Args:
119
+ level: int, an absl.logging level.
120
+
121
+ Raises:
122
+ TypeError: Raised when level is not an integer.
123
+
124
+ Returns:
125
+ The corresponding integer level for use in Abseil C++.
126
+ """
127
+ if not isinstance(level, int):
128
+ raise TypeError('Expect an int level, found {}'.format(type(level)))
129
+ if level >= 0:
130
+ # C++ log levels must be >= 0
131
+ return 0
132
+ else:
133
+ return -level
134
+
135
+
136
+ def absl_to_standard(level):
137
+ """Converts an integer level from the absl value to the standard value.
138
+
139
+ Args:
140
+ level: int, an absl.logging level.
141
+
142
+ Raises:
143
+ TypeError: Raised when level is not an integer.
144
+
145
+ Returns:
146
+ The corresponding integer level for use in standard logging.
147
+ """
148
+ if not isinstance(level, int):
149
+ raise TypeError('Expect an int level, found {}'.format(type(level)))
150
+ if level < ABSL_FATAL:
151
+ level = ABSL_FATAL
152
+ if level <= ABSL_DEBUG:
153
+ return ABSL_TO_STANDARD[level]
154
+ # Maps to vlog levels.
155
+ return STANDARD_DEBUG - level + 1
156
+
157
+
158
+ def string_to_standard(level):
159
+ """Converts a string level to standard logging level value.
160
+
161
+ Args:
162
+ level: str, case-insensitive ``'debug'``, ``'info'``, ``'warning'``,
163
+ ``'error'``, ``'fatal'``.
164
+
165
+ Returns:
166
+ The corresponding integer level for use in standard logging.
167
+ """
168
+ return absl_to_standard(ABSL_NAMES.get(level.upper()))
169
+
170
+
171
+ def standard_to_absl(level):
172
+ """Converts an integer level from the standard value to the absl value.
173
+
174
+ Args:
175
+ level: int, a Python standard logging level.
176
+
177
+ Raises:
178
+ TypeError: Raised when level is not an integer.
179
+
180
+ Returns:
181
+ The corresponding integer level for use in absl logging.
182
+ """
183
+ if not isinstance(level, int):
184
+ raise TypeError('Expect an int level, found {}'.format(type(level)))
185
+ if level < 0:
186
+ level = 0
187
+ if level < STANDARD_DEBUG:
188
+ # Maps to vlog levels.
189
+ return STANDARD_DEBUG - level + 1
190
+ elif level < STANDARD_INFO:
191
+ return ABSL_DEBUG
192
+ elif level < STANDARD_WARNING:
193
+ return ABSL_INFO
194
+ elif level < STANDARD_ERROR:
195
+ return ABSL_WARNING
196
+ elif level < STANDARD_CRITICAL:
197
+ return ABSL_ERROR
198
+ else:
199
+ return ABSL_FATAL
200
+
201
+
202
+ def standard_to_cpp(level):
203
+ """Converts an integer level from the standard value to the cpp value.
204
+
205
+ Args:
206
+ level: int, a Python standard logging level.
207
+
208
+ Raises:
209
+ TypeError: Raised when level is not an integer.
210
+
211
+ Returns:
212
+ The corresponding integer level for use in cpp logging.
213
+ """
214
+ return absl_to_cpp(standard_to_absl(level))
MLPY/Lib/site-packages/absl/testing/__init__.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2017 The Abseil Authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
MLPY/Lib/site-packages/absl/testing/__pycache__/__init__.cpython-39.pyc ADDED
Binary file (149 Bytes). View file
 
MLPY/Lib/site-packages/absl/testing/__pycache__/_bazelize_command.cpython-39.pyc ADDED
Binary file (1.61 kB). View file
 
MLPY/Lib/site-packages/absl/testing/__pycache__/_pretty_print_reporter.cpython-39.pyc ADDED
Binary file (3.2 kB). View file
 
MLPY/Lib/site-packages/absl/testing/__pycache__/absltest.cpython-39.pyc ADDED
Binary file (81.7 kB). View file
 
MLPY/Lib/site-packages/absl/testing/__pycache__/flagsaver.cpython-39.pyc ADDED
Binary file (12.7 kB). View file
 
MLPY/Lib/site-packages/absl/testing/__pycache__/parameterized.cpython-39.pyc ADDED
Binary file (23.6 kB). View file