Fork the tf_inspect to keras, which use tf_decorator.unwrap as __internal__ API.
PiperOrigin-RevId: 331660689 Change-Id: Ib7310b991986f71e0d7c2e9a53d7427e62db2d69
This commit is contained in:
parent
889e676a5e
commit
4ea067f6f5
@ -95,6 +95,7 @@ py_library(
|
||||
"//tensorflow/python/distribute:multi_worker_util",
|
||||
"//tensorflow/python/keras/engine:keras_tensor",
|
||||
"//tensorflow/python/keras/utils:control_flow_util",
|
||||
"//tensorflow/python/keras/utils:tf_inspect",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -55,6 +55,7 @@ from tensorflow.python.framework import tensor_util
|
||||
from tensorflow.python.keras import backend_config
|
||||
from tensorflow.python.keras.engine import keras_tensor
|
||||
from tensorflow.python.keras.utils import control_flow_util
|
||||
from tensorflow.python.keras.utils import tf_inspect
|
||||
from tensorflow.python.ops import array_ops
|
||||
from tensorflow.python.ops import clip_ops
|
||||
from tensorflow.python.ops import control_flow_ops
|
||||
@ -83,7 +84,6 @@ from tensorflow.python.util import dispatch
|
||||
from tensorflow.python.util import nest
|
||||
from tensorflow.python.util import object_identity
|
||||
from tensorflow.python.util import tf_contextlib
|
||||
from tensorflow.python.util import tf_inspect
|
||||
from tensorflow.python.util.tf_export import keras_export
|
||||
from tensorflow.tools.docs import doc_controls
|
||||
|
||||
|
@ -36,11 +36,11 @@ from tensorflow.python.keras import combinations
|
||||
from tensorflow.python.keras.engine import input_layer
|
||||
from tensorflow.python.keras.layers import advanced_activations
|
||||
from tensorflow.python.keras.layers import normalization
|
||||
from tensorflow.python.keras.utils import tf_inspect
|
||||
from tensorflow.python.ops import array_ops
|
||||
from tensorflow.python.ops import nn
|
||||
from tensorflow.python.ops import variables
|
||||
from tensorflow.python.platform import test
|
||||
from tensorflow.python.util import tf_inspect
|
||||
|
||||
|
||||
def compare_single_input_op_to_numpy(keras_op,
|
||||
|
@ -23,8 +23,8 @@ import six
|
||||
import tensorflow as tf
|
||||
|
||||
from tensorflow.python.eager import context
|
||||
from tensorflow.python.keras.utils import tf_inspect
|
||||
from tensorflow.python.platform import benchmark
|
||||
from tensorflow.python.util import tf_inspect
|
||||
|
||||
|
||||
def _run_benchmark(func, num_iters, execution_mode=None):
|
||||
|
@ -102,6 +102,7 @@ py_library(
|
||||
"//tensorflow/python/distribute:distribute_lib",
|
||||
"//tensorflow/python/eager:context",
|
||||
"//tensorflow/python/keras:backend",
|
||||
"//tensorflow/python/keras/utils:tf_inspect",
|
||||
"//tensorflow/python/keras/utils:tf_utils",
|
||||
],
|
||||
)
|
||||
|
@ -62,11 +62,13 @@ from tensorflow.python.keras.mixed_precision.experimental import policy
|
||||
from tensorflow.python.keras.saving.saved_model import layer_serialization
|
||||
from tensorflow.python.keras.utils import generic_utils
|
||||
from tensorflow.python.keras.utils import layer_utils
|
||||
from tensorflow.python.keras.utils import tf_inspect
|
||||
from tensorflow.python.keras.utils import tf_utils
|
||||
from tensorflow.python.keras.utils import version_utils
|
||||
# A module that only depends on `keras.layers` import these from here.
|
||||
from tensorflow.python.keras.utils.generic_utils import to_snake_case # pylint: disable=unused-import
|
||||
from tensorflow.python.keras.utils.tf_utils import is_tensor_or_tensor_list # pylint: disable=unused-import
|
||||
|
||||
from tensorflow.python.module import module
|
||||
from tensorflow.python.ops import array_ops
|
||||
from tensorflow.python.ops import math_ops
|
||||
@ -82,7 +84,6 @@ from tensorflow.python.training.tracking import tracking
|
||||
from tensorflow.python.util import compat
|
||||
from tensorflow.python.util import nest
|
||||
from tensorflow.python.util import object_identity
|
||||
from tensorflow.python.util import tf_inspect
|
||||
from tensorflow.python.util.tf_export import keras_export
|
||||
from tensorflow.tools.docs import doc_controls
|
||||
|
||||
|
@ -30,6 +30,7 @@ from tensorflow.python.framework import tensor_shape
|
||||
from tensorflow.python.framework import tensor_util
|
||||
from tensorflow.python.keras import backend
|
||||
from tensorflow.python.keras.utils import control_flow_util
|
||||
from tensorflow.python.keras.utils import tf_inspect
|
||||
from tensorflow.python.keras.utils import tf_utils
|
||||
from tensorflow.python.ops import array_ops
|
||||
from tensorflow.python.ops import control_flow_util_v2
|
||||
@ -37,7 +38,6 @@ from tensorflow.python.ops import variables as tf_variables
|
||||
from tensorflow.python.ops.ragged import ragged_tensor
|
||||
from tensorflow.python.training.tracking import base as tracking
|
||||
from tensorflow.python.util import nest
|
||||
from tensorflow.python.util import tf_inspect
|
||||
from tensorflow.python.util.tf_export import keras_export
|
||||
|
||||
_call_context = threading.local()
|
||||
|
@ -52,6 +52,7 @@ from tensorflow.python.keras.mixed_precision.experimental import policy
|
||||
from tensorflow.python.keras.saving.saved_model import layer_serialization
|
||||
from tensorflow.python.keras.utils import generic_utils
|
||||
from tensorflow.python.keras.utils import layer_utils
|
||||
from tensorflow.python.keras.utils import tf_inspect
|
||||
from tensorflow.python.keras.utils import tf_utils
|
||||
# A module that only depends on `keras.layers` import these from here.
|
||||
from tensorflow.python.keras.utils.generic_utils import to_snake_case # pylint: disable=unused-import
|
||||
@ -69,7 +70,6 @@ from tensorflow.python.training.tracking import layer_utils as trackable_layer_u
|
||||
from tensorflow.python.training.tracking import tracking
|
||||
from tensorflow.python.util import nest
|
||||
from tensorflow.python.util import object_identity
|
||||
from tensorflow.python.util import tf_inspect
|
||||
from tensorflow.tools.docs import doc_controls
|
||||
|
||||
|
||||
|
@ -40,13 +40,13 @@ from tensorflow.python.keras.engine import training as training_lib
|
||||
from tensorflow.python.keras.engine import training_utils
|
||||
from tensorflow.python.keras.saving.saved_model import network_serialization
|
||||
from tensorflow.python.keras.utils import generic_utils
|
||||
from tensorflow.python.keras.utils import tf_inspect
|
||||
from tensorflow.python.keras.utils import tf_utils
|
||||
from tensorflow.python.ops import array_ops
|
||||
from tensorflow.python.ops import math_ops
|
||||
from tensorflow.python.platform import tf_logging as logging
|
||||
from tensorflow.python.training.tracking import base as trackable
|
||||
from tensorflow.python.util import nest
|
||||
from tensorflow.python.util import tf_inspect
|
||||
|
||||
|
||||
# pylint: disable=g-classes-have-attributes
|
||||
|
@ -33,12 +33,12 @@ from tensorflow.python.keras.engine import training_utils
|
||||
from tensorflow.python.keras.saving.saved_model import model_serialization
|
||||
from tensorflow.python.keras.utils import generic_utils
|
||||
from tensorflow.python.keras.utils import layer_utils
|
||||
from tensorflow.python.keras.utils import tf_inspect
|
||||
from tensorflow.python.keras.utils import tf_utils
|
||||
from tensorflow.python.ops.numpy_ops import np_arrays
|
||||
from tensorflow.python.platform import tf_logging as logging
|
||||
from tensorflow.python.training.tracking import base as trackable
|
||||
from tensorflow.python.util import nest
|
||||
from tensorflow.python.util import tf_inspect
|
||||
from tensorflow.python.util.tf_export import keras_export
|
||||
|
||||
|
||||
|
@ -51,13 +51,13 @@ from tensorflow.python.keras import metrics as metrics_module
|
||||
from tensorflow.python.keras.utils import data_utils
|
||||
from tensorflow.python.keras.utils import generic_utils
|
||||
from tensorflow.python.keras.utils import losses_utils
|
||||
from tensorflow.python.keras.utils import tf_inspect
|
||||
from tensorflow.python.ops import array_ops
|
||||
from tensorflow.python.ops import gen_array_ops
|
||||
from tensorflow.python.ops import math_ops
|
||||
from tensorflow.python.ops.ragged import ragged_tensor
|
||||
from tensorflow.python.platform import tf_logging as logging
|
||||
from tensorflow.python.util import nest
|
||||
from tensorflow.python.util import tf_inspect
|
||||
from tensorflow.python.util.compat import collections_abc
|
||||
|
||||
|
||||
|
@ -55,6 +55,7 @@ from tensorflow.python.keras.optimizer_v2 import optimizer_v2
|
||||
from tensorflow.python.keras.saving.saved_model import model_serialization
|
||||
from tensorflow.python.keras.utils import data_utils
|
||||
from tensorflow.python.keras.utils import losses_utils
|
||||
from tensorflow.python.keras.utils import tf_inspect
|
||||
from tensorflow.python.keras.utils.mode_keys import ModeKeys
|
||||
from tensorflow.python.ops import array_ops
|
||||
from tensorflow.python.ops import math_ops
|
||||
@ -63,7 +64,6 @@ from tensorflow.python.training.tracking import base as trackable
|
||||
from tensorflow.python.training.tracking import layer_utils as trackable_layer_utils
|
||||
from tensorflow.python.types import core
|
||||
from tensorflow.python.util import nest
|
||||
from tensorflow.python.util import tf_inspect
|
||||
from tensorflow.python.util.compat import collections_abc
|
||||
|
||||
try:
|
||||
|
@ -25,8 +25,8 @@ from tensorflow.python import tf2
|
||||
from tensorflow.python.keras.initializers import initializers_v1
|
||||
from tensorflow.python.keras.initializers import initializers_v2
|
||||
from tensorflow.python.keras.utils import generic_utils
|
||||
from tensorflow.python.keras.utils import tf_inspect as inspect
|
||||
from tensorflow.python.ops import init_ops
|
||||
from tensorflow.python.util import tf_inspect as inspect
|
||||
from tensorflow.python.util.tf_export import keras_export
|
||||
|
||||
|
||||
|
@ -46,6 +46,7 @@ from tensorflow.python.keras.layers.ops import core as core_ops
|
||||
from tensorflow.python.keras.utils import control_flow_util
|
||||
from tensorflow.python.keras.utils import conv_utils
|
||||
from tensorflow.python.keras.utils import generic_utils
|
||||
from tensorflow.python.keras.utils import tf_inspect
|
||||
from tensorflow.python.keras.utils import tf_utils
|
||||
from tensorflow.python.ops import array_ops
|
||||
from tensorflow.python.ops import gen_array_ops
|
||||
@ -57,7 +58,6 @@ from tensorflow.python.training.tracking import base as trackable
|
||||
from tensorflow.python.util import dispatch
|
||||
from tensorflow.python.util import nest
|
||||
from tensorflow.python.util import tf_decorator
|
||||
from tensorflow.python.util import tf_inspect
|
||||
from tensorflow.python.util.tf_export import get_canonical_name_for_symbol
|
||||
from tensorflow.python.util.tf_export import get_symbol_from_name
|
||||
from tensorflow.python.util.tf_export import keras_export
|
||||
|
@ -26,8 +26,8 @@ from __future__ import print_function
|
||||
|
||||
|
||||
from tensorflow.python.keras.layers import recurrent
|
||||
from tensorflow.python.keras.utils import tf_inspect
|
||||
from tensorflow.python.ops import rnn_cell_wrapper_impl
|
||||
from tensorflow.python.util import tf_inspect
|
||||
from tensorflow.python.util.tf_export import tf_export
|
||||
|
||||
|
||||
|
@ -61,7 +61,7 @@ from tensorflow.python.keras.layers.preprocessing import string_lookup_v1 as pre
|
||||
from tensorflow.python.keras.layers.preprocessing import text_vectorization as preprocessing_text_vectorization
|
||||
from tensorflow.python.keras.layers.preprocessing import text_vectorization_v1 as preprocessing_text_vectorization_v1
|
||||
from tensorflow.python.keras.utils import generic_utils
|
||||
from tensorflow.python.util import tf_inspect as inspect
|
||||
from tensorflow.python.keras.utils import tf_inspect as inspect
|
||||
from tensorflow.python.util.tf_export import keras_export
|
||||
|
||||
|
||||
|
@ -29,11 +29,11 @@ from tensorflow.python.keras.engine.input_spec import InputSpec
|
||||
from tensorflow.python.keras.layers.recurrent import _standardize_args
|
||||
from tensorflow.python.keras.utils import generic_utils
|
||||
from tensorflow.python.keras.utils import layer_utils
|
||||
from tensorflow.python.keras.utils import tf_inspect
|
||||
from tensorflow.python.keras.utils import tf_utils
|
||||
from tensorflow.python.ops import array_ops
|
||||
from tensorflow.python.ops.ragged import ragged_tensor
|
||||
from tensorflow.python.util import nest
|
||||
from tensorflow.python.util import tf_inspect
|
||||
from tensorflow.python.util.tf_export import keras_export
|
||||
|
||||
|
||||
|
@ -56,6 +56,7 @@ from tensorflow.python.keras.losses import squared_hinge
|
||||
from tensorflow.python.keras.saving.saved_model import metric_serialization
|
||||
from tensorflow.python.keras.utils import losses_utils
|
||||
from tensorflow.python.keras.utils import metrics_utils
|
||||
from tensorflow.python.keras.utils import tf_inspect
|
||||
from tensorflow.python.keras.utils.generic_utils import deserialize_keras_object
|
||||
from tensorflow.python.keras.utils.generic_utils import serialize_keras_object
|
||||
from tensorflow.python.keras.utils.generic_utils import to_list
|
||||
@ -72,7 +73,6 @@ from tensorflow.python.ops import weights_broadcast_ops
|
||||
from tensorflow.python.training.tracking import base as trackable
|
||||
from tensorflow.python.util import dispatch
|
||||
from tensorflow.python.util import nest
|
||||
from tensorflow.python.util import tf_inspect
|
||||
from tensorflow.python.util.tf_export import keras_export
|
||||
from tensorflow.tools.docs import doc_controls
|
||||
|
||||
|
@ -40,6 +40,7 @@ from tensorflow.python.keras.optimizer_v2 import learning_rate_schedule
|
||||
from tensorflow.python.keras.optimizer_v2 import utils as optimizer_utils
|
||||
from tensorflow.python.keras.utils import generic_utils
|
||||
from tensorflow.python.keras.utils import layer_utils
|
||||
from tensorflow.python.keras.utils import tf_inspect
|
||||
from tensorflow.python.keras.utils import tf_utils
|
||||
from tensorflow.python.ops import array_ops
|
||||
from tensorflow.python.ops import control_flow_ops
|
||||
@ -50,7 +51,6 @@ from tensorflow.python.ops import variables as tf_variables
|
||||
from tensorflow.python.saved_model import revived_types
|
||||
from tensorflow.python.training.tracking import base as trackable
|
||||
from tensorflow.python.util import nest
|
||||
from tensorflow.python.util import tf_inspect
|
||||
from tensorflow.python.util.tf_export import keras_export
|
||||
|
||||
|
||||
|
@ -33,11 +33,11 @@ from tensorflow.python.framework import ops
|
||||
from tensorflow.python.keras import backend
|
||||
from tensorflow.python.keras.preprocessing.image_dataset import image_dataset_from_directory # pylint: disable=unused-import
|
||||
from tensorflow.python.keras.utils import data_utils
|
||||
from tensorflow.python.keras.utils import tf_inspect
|
||||
from tensorflow.python.ops import array_ops
|
||||
from tensorflow.python.ops import image_ops
|
||||
from tensorflow.python.ops import math_ops
|
||||
from tensorflow.python.platform import tf_logging
|
||||
from tensorflow.python.util import tf_inspect
|
||||
from tensorflow.python.util.tf_export import keras_export
|
||||
|
||||
random_rotation = image.random_rotation
|
||||
|
@ -37,6 +37,7 @@ from tensorflow.python.keras.saving.saved_model import constants
|
||||
from tensorflow.python.keras.saving.saved_model import load as keras_load
|
||||
from tensorflow.python.keras.saving.saved_model import serialized_attributes
|
||||
from tensorflow.python.keras.saving.saved_model import utils
|
||||
from tensorflow.python.keras.utils import tf_inspect
|
||||
from tensorflow.python.keras.utils import version_utils
|
||||
from tensorflow.python.keras.utils.generic_utils import LazyLoader
|
||||
from tensorflow.python.platform import tf_logging as logging
|
||||
@ -44,7 +45,6 @@ from tensorflow.python.training.tracking import base as trackable
|
||||
from tensorflow.python.training.tracking import data_structures
|
||||
from tensorflow.python.util import nest
|
||||
from tensorflow.python.util import tf_decorator
|
||||
from tensorflow.python.util import tf_inspect
|
||||
|
||||
# To avoid circular dependencies between keras/engine and keras/saving,
|
||||
# code in keras/saving must delay imports.
|
||||
|
@ -53,6 +53,7 @@ from tensorflow.python.keras.saving.saved_model import load as keras_load
|
||||
from tensorflow.python.keras.saving.saved_model import save_impl as keras_save
|
||||
from tensorflow.python.keras.utils import control_flow_util
|
||||
from tensorflow.python.keras.utils import generic_utils
|
||||
from tensorflow.python.keras.utils import tf_inspect
|
||||
from tensorflow.python.ops import array_ops
|
||||
from tensorflow.python.ops import init_ops
|
||||
from tensorflow.python.ops import math_ops
|
||||
@ -63,7 +64,6 @@ from tensorflow.python.platform import test
|
||||
from tensorflow.python.saved_model import load as tf_load
|
||||
from tensorflow.python.saved_model import save as tf_save
|
||||
from tensorflow.python.util import tf_contextlib
|
||||
from tensorflow.python.util import tf_inspect
|
||||
|
||||
|
||||
class LayerWithLearningPhase(keras.engine.base_layer.Layer):
|
||||
|
@ -24,10 +24,10 @@ from tensorflow.python.eager import context
|
||||
from tensorflow.python.keras import backend as K
|
||||
from tensorflow.python.keras.engine import base_layer_utils
|
||||
from tensorflow.python.keras.utils import control_flow_util
|
||||
from tensorflow.python.keras.utils import tf_inspect
|
||||
from tensorflow.python.keras.utils.generic_utils import LazyLoader
|
||||
from tensorflow.python.training.tracking import layer_utils as trackable_layer_utils
|
||||
from tensorflow.python.util import tf_decorator
|
||||
from tensorflow.python.util import tf_inspect
|
||||
|
||||
|
||||
# pylint:disable=g-inconsistent-quotes
|
||||
|
@ -46,9 +46,9 @@ from tensorflow.python.keras.optimizer_v2 import adamax as adamax_v2
|
||||
from tensorflow.python.keras.optimizer_v2 import gradient_descent as gradient_descent_v2
|
||||
from tensorflow.python.keras.optimizer_v2 import nadam as nadam_v2
|
||||
from tensorflow.python.keras.optimizer_v2 import rmsprop as rmsprop_v2
|
||||
from tensorflow.python.keras.utils import tf_inspect
|
||||
from tensorflow.python.util import tf_contextlib
|
||||
from tensorflow.python.util import tf_decorator
|
||||
from tensorflow.python.util import tf_inspect
|
||||
|
||||
|
||||
def string_test(actual, expected):
|
||||
|
@ -197,6 +197,15 @@ py_library(
|
||||
],
|
||||
)
|
||||
|
||||
py_library(
|
||||
name = "tf_inspect",
|
||||
srcs = ["tf_inspect.py"],
|
||||
srcs_version = "PY2AND3",
|
||||
deps = [
|
||||
"//tensorflow/python:util",
|
||||
],
|
||||
)
|
||||
|
||||
py_library(
|
||||
name = "vis_utils",
|
||||
srcs = [
|
||||
|
@ -45,11 +45,11 @@ from six.moves.urllib.error import URLError
|
||||
|
||||
from tensorflow.python.framework import ops
|
||||
from six.moves.urllib.request import urlopen
|
||||
from tensorflow.python.keras.utils import tf_inspect
|
||||
from tensorflow.python.keras.utils.generic_utils import Progbar
|
||||
from tensorflow.python.keras.utils.io_utils import path_to_string
|
||||
from tensorflow.python.platform import tf_logging as logging
|
||||
from tensorflow.python.util import deprecation
|
||||
from tensorflow.python.util import tf_inspect
|
||||
from tensorflow.python.util.tf_export import keras_export
|
||||
|
||||
|
||||
|
@ -29,11 +29,10 @@ import types as python_types
|
||||
|
||||
import numpy as np
|
||||
import six
|
||||
|
||||
from tensorflow.python.keras.utils import tf_inspect
|
||||
from tensorflow.python.util import nest
|
||||
from tensorflow.python.util import tf_contextlib
|
||||
from tensorflow.python.util import tf_decorator
|
||||
from tensorflow.python.util import tf_inspect
|
||||
from tensorflow.python.util.tf_export import keras_export
|
||||
|
||||
_GLOBAL_CUSTOM_OBJECTS = {}
|
||||
|
402
tensorflow/python/keras/utils/tf_inspect.py
Normal file
402
tensorflow/python/keras/utils/tf_inspect.py
Normal file
@ -0,0 +1,402 @@
|
||||
# Copyright 2017 The TensorFlow Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# ==============================================================================
|
||||
"""TFDecorator-aware replacements for the inspect module."""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import collections
|
||||
import functools
|
||||
import inspect as _inspect
|
||||
|
||||
import six
|
||||
|
||||
from tensorflow.python.util import tf_decorator
|
||||
|
||||
ArgSpec = _inspect.ArgSpec
|
||||
|
||||
|
||||
if hasattr(_inspect, 'FullArgSpec'):
|
||||
FullArgSpec = _inspect.FullArgSpec # pylint: disable=invalid-name
|
||||
else:
|
||||
FullArgSpec = collections.namedtuple('FullArgSpec', [
|
||||
'args', 'varargs', 'varkw', 'defaults', 'kwonlyargs', 'kwonlydefaults',
|
||||
'annotations'
|
||||
])
|
||||
|
||||
|
||||
def _convert_maybe_argspec_to_fullargspec(argspec):
|
||||
if isinstance(argspec, FullArgSpec):
|
||||
return argspec
|
||||
return FullArgSpec(
|
||||
args=argspec.args,
|
||||
varargs=argspec.varargs,
|
||||
varkw=argspec.keywords,
|
||||
defaults=argspec.defaults,
|
||||
kwonlyargs=[],
|
||||
kwonlydefaults=None,
|
||||
annotations={})
|
||||
|
||||
if hasattr(_inspect, 'getfullargspec'):
|
||||
_getfullargspec = _inspect.getfullargspec # pylint: disable=invalid-name
|
||||
|
||||
def _getargspec(target):
|
||||
"""A python3 version of getargspec.
|
||||
|
||||
Calls `getfullargspec` and assigns args, varargs,
|
||||
varkw, and defaults to a python 2/3 compatible `ArgSpec`.
|
||||
|
||||
The parameter name 'varkw' is changed to 'keywords' to fit the
|
||||
`ArgSpec` struct.
|
||||
|
||||
Args:
|
||||
target: the target object to inspect.
|
||||
|
||||
Returns:
|
||||
An ArgSpec with args, varargs, keywords, and defaults parameters
|
||||
from FullArgSpec.
|
||||
"""
|
||||
fullargspecs = getfullargspec(target)
|
||||
argspecs = ArgSpec(
|
||||
args=fullargspecs.args,
|
||||
varargs=fullargspecs.varargs,
|
||||
keywords=fullargspecs.varkw,
|
||||
defaults=fullargspecs.defaults)
|
||||
return argspecs
|
||||
else:
|
||||
_getargspec = _inspect.getargspec
|
||||
|
||||
def _getfullargspec(target):
|
||||
"""A python2 version of getfullargspec.
|
||||
|
||||
Args:
|
||||
target: the target object to inspect.
|
||||
|
||||
Returns:
|
||||
A FullArgSpec with empty kwonlyargs, kwonlydefaults and annotations.
|
||||
"""
|
||||
return _convert_maybe_argspec_to_fullargspec(getargspec(target))
|
||||
|
||||
|
||||
def getargspec(obj):
|
||||
"""TFDecorator-aware replacement for `inspect.getargspec`.
|
||||
|
||||
Note: `getfullargspec` is recommended as the python 2/3 compatible
|
||||
replacement for this function.
|
||||
|
||||
Args:
|
||||
obj: A function, partial function, or callable object, possibly decorated.
|
||||
|
||||
Returns:
|
||||
The `ArgSpec` that describes the signature of the outermost decorator that
|
||||
changes the callable's signature, or the `ArgSpec` that describes
|
||||
the object if not decorated.
|
||||
|
||||
Raises:
|
||||
ValueError: When callable's signature can not be expressed with
|
||||
ArgSpec.
|
||||
TypeError: For objects of unsupported types.
|
||||
"""
|
||||
if isinstance(obj, functools.partial):
|
||||
return _get_argspec_for_partial(obj)
|
||||
|
||||
decorators, target = tf_decorator.unwrap(obj)
|
||||
|
||||
spec = next((d.decorator_argspec
|
||||
for d in decorators
|
||||
if d.decorator_argspec is not None), None)
|
||||
if spec:
|
||||
return spec
|
||||
|
||||
try:
|
||||
# Python3 will handle most callables here (not partial).
|
||||
return _getargspec(target)
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
if isinstance(target, type):
|
||||
try:
|
||||
return _getargspec(target.__init__)
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
try:
|
||||
return _getargspec(target.__new__)
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
# The `type(target)` ensures that if a class is received we don't return
|
||||
# the signature of its __call__ method.
|
||||
return _getargspec(type(target).__call__)
|
||||
|
||||
|
||||
def _get_argspec_for_partial(obj):
|
||||
"""Implements `getargspec` for `functools.partial` objects.
|
||||
|
||||
Args:
|
||||
obj: The `functools.partial` object
|
||||
Returns:
|
||||
An `inspect.ArgSpec`
|
||||
Raises:
|
||||
ValueError: When callable's signature can not be expressed with
|
||||
ArgSpec.
|
||||
"""
|
||||
# When callable is a functools.partial object, we construct its ArgSpec with
|
||||
# following strategy:
|
||||
# - If callable partial contains default value for positional arguments (ie.
|
||||
# object.args), then final ArgSpec doesn't contain those positional arguments.
|
||||
# - If callable partial contains default value for keyword arguments (ie.
|
||||
# object.keywords), then we merge them with wrapped target. Default values
|
||||
# from callable partial takes precedence over those from wrapped target.
|
||||
#
|
||||
# However, there is a case where it is impossible to construct a valid
|
||||
# ArgSpec. Python requires arguments that have no default values must be
|
||||
# defined before those with default values. ArgSpec structure is only valid
|
||||
# when this presumption holds true because default values are expressed as a
|
||||
# tuple of values without keywords and they are always assumed to belong to
|
||||
# last K arguments where K is number of default values present.
|
||||
#
|
||||
# Since functools.partial can give default value to any argument, this
|
||||
# presumption may no longer hold in some cases. For example:
|
||||
#
|
||||
# def func(m, n):
|
||||
# return 2 * m + n
|
||||
# partialed = functools.partial(func, m=1)
|
||||
#
|
||||
# This example will result in m having a default value but n doesn't. This is
|
||||
# usually not allowed in Python and can not be expressed in ArgSpec correctly.
|
||||
#
|
||||
# Thus, we must detect cases like this by finding first argument with default
|
||||
# value and ensures all following arguments also have default values. When
|
||||
# this is not true, a ValueError is raised.
|
||||
|
||||
n_prune_args = len(obj.args)
|
||||
partial_keywords = obj.keywords or {}
|
||||
|
||||
args, varargs, keywords, defaults = getargspec(obj.func)
|
||||
|
||||
# Pruning first n_prune_args arguments.
|
||||
args = args[n_prune_args:]
|
||||
|
||||
# Partial function may give default value to any argument, therefore length
|
||||
# of default value list must be len(args) to allow each argument to
|
||||
# potentially be given a default value.
|
||||
no_default = object()
|
||||
all_defaults = [no_default] * len(args)
|
||||
|
||||
if defaults:
|
||||
all_defaults[-len(defaults):] = defaults
|
||||
|
||||
# Fill in default values provided by partial function in all_defaults.
|
||||
for kw, default in six.iteritems(partial_keywords):
|
||||
if kw in args:
|
||||
idx = args.index(kw)
|
||||
all_defaults[idx] = default
|
||||
elif not keywords:
|
||||
raise ValueError('Function does not have **kwargs parameter, but '
|
||||
'contains an unknown partial keyword.')
|
||||
|
||||
# Find first argument with default value set.
|
||||
first_default = next(
|
||||
(idx for idx, x in enumerate(all_defaults) if x is not no_default), None)
|
||||
|
||||
# If no default values are found, return ArgSpec with defaults=None.
|
||||
if first_default is None:
|
||||
return ArgSpec(args, varargs, keywords, None)
|
||||
|
||||
# Checks if all arguments have default value set after first one.
|
||||
invalid_default_values = [
|
||||
args[i] for i, j in enumerate(all_defaults)
|
||||
if j is no_default and i > first_default
|
||||
]
|
||||
|
||||
if invalid_default_values:
|
||||
raise ValueError('Some arguments %s do not have default value, but they '
|
||||
'are positioned after those with default values. This can '
|
||||
'not be expressed with ArgSpec.' % invalid_default_values)
|
||||
|
||||
return ArgSpec(args, varargs, keywords, tuple(all_defaults[first_default:]))
|
||||
|
||||
|
||||
def getfullargspec(obj):
|
||||
"""TFDecorator-aware replacement for `inspect.getfullargspec`.
|
||||
|
||||
This wrapper emulates `inspect.getfullargspec` in[^)]* Python2.
|
||||
|
||||
Args:
|
||||
obj: A callable, possibly decorated.
|
||||
|
||||
Returns:
|
||||
The `FullArgSpec` that describes the signature of
|
||||
the outermost decorator that changes the callable's signature. If the
|
||||
callable is not decorated, `inspect.getfullargspec()` will be called
|
||||
directly on the callable.
|
||||
"""
|
||||
decorators, target = tf_decorator.unwrap(obj)
|
||||
|
||||
for d in decorators:
|
||||
if d.decorator_argspec is not None:
|
||||
return _convert_maybe_argspec_to_fullargspec(d.decorator_argspec)
|
||||
return _getfullargspec(target)
|
||||
|
||||
|
||||
def getcallargs(*func_and_positional, **named):
|
||||
"""TFDecorator-aware replacement for inspect.getcallargs.
|
||||
|
||||
Args:
|
||||
*func_and_positional: A callable, possibly decorated, followed by any
|
||||
positional arguments that would be passed to `func`.
|
||||
**named: The named argument dictionary that would be passed to `func`.
|
||||
|
||||
Returns:
|
||||
A dictionary mapping `func`'s named arguments to the values they would
|
||||
receive if `func(*positional, **named)` were called.
|
||||
|
||||
`getcallargs` will use the argspec from the outermost decorator that provides
|
||||
it. If no attached decorators modify argspec, the final unwrapped target's
|
||||
argspec will be used.
|
||||
"""
|
||||
func = func_and_positional[0]
|
||||
positional = func_and_positional[1:]
|
||||
argspec = getfullargspec(func)
|
||||
call_args = named.copy()
|
||||
this = getattr(func, 'im_self', None) or getattr(func, '__self__', None)
|
||||
if ismethod(func) and this:
|
||||
positional = (this,) + positional
|
||||
remaining_positionals = [arg for arg in argspec.args if arg not in call_args]
|
||||
call_args.update(dict(zip(remaining_positionals, positional)))
|
||||
default_count = 0 if not argspec.defaults else len(argspec.defaults)
|
||||
if default_count:
|
||||
for arg, value in zip(argspec.args[-default_count:], argspec.defaults):
|
||||
if arg not in call_args:
|
||||
call_args[arg] = value
|
||||
if argspec.kwonlydefaults is not None:
|
||||
for k, v in argspec.kwonlydefaults.items():
|
||||
if k not in call_args:
|
||||
call_args[k] = v
|
||||
return call_args
|
||||
|
||||
|
||||
def getframeinfo(*args, **kwargs):
|
||||
return _inspect.getframeinfo(*args, **kwargs)
|
||||
|
||||
|
||||
def getdoc(object): # pylint: disable=redefined-builtin
|
||||
"""TFDecorator-aware replacement for inspect.getdoc.
|
||||
|
||||
Args:
|
||||
object: An object, possibly decorated.
|
||||
|
||||
Returns:
|
||||
The docstring associated with the object.
|
||||
|
||||
The outermost-decorated object is intended to have the most complete
|
||||
documentation, so the decorated parameter is not unwrapped.
|
||||
"""
|
||||
return _inspect.getdoc(object)
|
||||
|
||||
|
||||
def getfile(object): # pylint: disable=redefined-builtin
|
||||
"""TFDecorator-aware replacement for inspect.getfile."""
|
||||
unwrapped_object = tf_decorator.unwrap(object)[1]
|
||||
|
||||
# Work around for the case when object is a stack frame
|
||||
# and only .pyc files are used. In this case, getfile
|
||||
# might return incorrect path. So, we get the path from f_globals
|
||||
# instead.
|
||||
if (hasattr(unwrapped_object, 'f_globals') and
|
||||
'__file__' in unwrapped_object.f_globals):
|
||||
return unwrapped_object.f_globals['__file__']
|
||||
return _inspect.getfile(unwrapped_object)
|
||||
|
||||
|
||||
def getmembers(object, predicate=None): # pylint: disable=redefined-builtin
|
||||
"""TFDecorator-aware replacement for inspect.getmembers."""
|
||||
return _inspect.getmembers(object, predicate)
|
||||
|
||||
|
||||
def getmodule(object): # pylint: disable=redefined-builtin
|
||||
"""TFDecorator-aware replacement for inspect.getmodule."""
|
||||
return _inspect.getmodule(object)
|
||||
|
||||
|
||||
def getmro(cls):
|
||||
"""TFDecorator-aware replacement for inspect.getmro."""
|
||||
return _inspect.getmro(cls)
|
||||
|
||||
|
||||
def getsource(object): # pylint: disable=redefined-builtin
|
||||
"""TFDecorator-aware replacement for inspect.getsource."""
|
||||
return _inspect.getsource(tf_decorator.unwrap(object)[1])
|
||||
|
||||
|
||||
def getsourcefile(object): # pylint: disable=redefined-builtin
|
||||
"""TFDecorator-aware replacement for inspect.getsourcefile."""
|
||||
return _inspect.getsourcefile(tf_decorator.unwrap(object)[1])
|
||||
|
||||
|
||||
def getsourcelines(object): # pylint: disable=redefined-builtin
|
||||
"""TFDecorator-aware replacement for inspect.getsourcelines."""
|
||||
return _inspect.getsourcelines(tf_decorator.unwrap(object)[1])
|
||||
|
||||
|
||||
def isbuiltin(object): # pylint: disable=redefined-builtin
|
||||
"""TFDecorator-aware replacement for inspect.isbuiltin."""
|
||||
return _inspect.isbuiltin(tf_decorator.unwrap(object)[1])
|
||||
|
||||
|
||||
def isclass(object): # pylint: disable=redefined-builtin
|
||||
"""TFDecorator-aware replacement for inspect.isclass."""
|
||||
return _inspect.isclass(tf_decorator.unwrap(object)[1])
|
||||
|
||||
|
||||
def isfunction(object): # pylint: disable=redefined-builtin
|
||||
"""TFDecorator-aware replacement for inspect.isfunction."""
|
||||
return _inspect.isfunction(tf_decorator.unwrap(object)[1])
|
||||
|
||||
|
||||
def isframe(object): # pylint: disable=redefined-builtin
|
||||
"""TFDecorator-aware replacement for inspect.ismodule."""
|
||||
return _inspect.isframe(tf_decorator.unwrap(object)[1])
|
||||
|
||||
|
||||
def isgenerator(object): # pylint: disable=redefined-builtin
|
||||
"""TFDecorator-aware replacement for inspect.isgenerator."""
|
||||
return _inspect.isgenerator(tf_decorator.unwrap(object)[1])
|
||||
|
||||
|
||||
def isgeneratorfunction(object): # pylint: disable=redefined-builtin
|
||||
"""TFDecorator-aware replacement for inspect.isgeneratorfunction."""
|
||||
return _inspect.isgeneratorfunction(tf_decorator.unwrap(object)[1])
|
||||
|
||||
|
||||
def ismethod(object): # pylint: disable=redefined-builtin
|
||||
"""TFDecorator-aware replacement for inspect.ismethod."""
|
||||
return _inspect.ismethod(tf_decorator.unwrap(object)[1])
|
||||
|
||||
|
||||
def ismodule(object): # pylint: disable=redefined-builtin
|
||||
"""TFDecorator-aware replacement for inspect.ismodule."""
|
||||
return _inspect.ismodule(tf_decorator.unwrap(object)[1])
|
||||
|
||||
|
||||
def isroutine(object): # pylint: disable=redefined-builtin
|
||||
"""TFDecorator-aware replacement for inspect.isroutine."""
|
||||
return _inspect.isroutine(tf_decorator.unwrap(object)[1])
|
||||
|
||||
|
||||
def stack(context=1):
|
||||
"""TFDecorator-aware replacement for inspect.stack."""
|
||||
return _inspect.stack(context)[1:]
|
Loading…
Reference in New Issue
Block a user