1# Copyright 2015 The TensorFlow Authors. All Rights Reserved. 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 16"""Import router for absl.flags. See https://github.com/abseil/abseil-py.""" 17from __future__ import absolute_import 18from __future__ import division 19from __future__ import print_function 20 21import logging as _logging 22import sys as _sys 23 24# go/tf-wildcard-import 25 26from absl.flags import * # pylint: disable=wildcard-import 27import six as _six 28 29from tensorflow.python.util import tf_decorator 30 31 32# Since we wrap absl.flags DEFINE functions, we need to declare this module 33# does not affect key flags. 34disclaim_key_flags() # pylint: disable=undefined-variable 35 36 37_RENAMED_ARGUMENTS = { 38 'flag_name': 'name', 39 'default_value': 'default', 40 'docstring': 'help', 41} 42 43 44def _wrap_define_function(original_function): 45 """Wraps absl.flags's define functions so tf.flags accepts old names.""" 46 47 def wrapper(*args, **kwargs): 48 """Wrapper function that turns old keyword names to new ones.""" 49 has_old_names = False 50 for old_name, new_name in _six.iteritems(_RENAMED_ARGUMENTS): 51 if old_name in kwargs: 52 has_old_names = True 53 value = kwargs.pop(old_name) 54 kwargs[new_name] = value 55 if has_old_names: 56 _logging.warning( 57 'Use of the keyword argument names (flag_name, default_value, ' 58 'docstring) is deprecated, please use (name, default, help) instead.') 59 return original_function(*args, **kwargs) 60 61 return tf_decorator.make_decorator(original_function, wrapper) 62 63 64class _FlagValuesWrapper(object): 65 """Wrapper class for absl.flags.FLAGS. 66 67 The difference is that tf.flags.FLAGS implicitly parses flags with sys.argv 68 when accessing the FLAGS values before it's explicitly parsed, 69 while absl.flags.FLAGS raises an exception. 70 """ 71 72 def __init__(self, flags_object): 73 self.__dict__['__wrapped'] = flags_object 74 75 def __getattribute__(self, name): 76 if name == '__dict__': 77 return super(_FlagValuesWrapper, self).__getattribute__(name) 78 return self.__dict__['__wrapped'].__getattribute__(name) 79 80 def __getattr__(self, name): 81 wrapped = self.__dict__['__wrapped'] 82 # To maintain backwards compatibility, implicitly parse flags when reading 83 # a flag. 84 if not wrapped.is_parsed(): 85 wrapped(_sys.argv) 86 return wrapped.__getattr__(name) 87 88 def __setattr__(self, name, value): 89 return self.__dict__['__wrapped'].__setattr__(name, value) 90 91 def __delattr__(self, name): 92 return self.__dict__['__wrapped'].__delattr__(name) 93 94 def __dir__(self): 95 return self.__dict__['__wrapped'].__dir__() 96 97 def __getitem__(self, name): 98 return self.__dict__['__wrapped'].__getitem__(name) 99 100 def __setitem__(self, name, flag): 101 return self.__dict__['__wrapped'].__setitem__(name, flag) 102 103 def __len__(self): 104 return self.__dict__['__wrapped'].__len__() 105 106 def __iter__(self): 107 return self.__dict__['__wrapped'].__iter__() 108 109 def __str__(self): 110 return self.__dict__['__wrapped'].__str__() 111 112 def __call__(self, *args, **kwargs): 113 return self.__dict__['__wrapped'].__call__(*args, **kwargs) 114 115 116# pylint: disable=invalid-name,used-before-assignment 117# absl.flags APIs use `default` as the name of the default value argument. 118# Allow the following functions continue to accept `default_value`. 119DEFINE_string = _wrap_define_function(DEFINE_string) 120DEFINE_boolean = _wrap_define_function(DEFINE_boolean) 121DEFINE_bool = DEFINE_boolean 122DEFINE_float = _wrap_define_function(DEFINE_float) 123DEFINE_integer = _wrap_define_function(DEFINE_integer) 124# pylint: enable=invalid-name,used-before-assignment 125 126FLAGS = _FlagValuesWrapper(FLAGS) # pylint: disable=used-before-assignment 127