Intelegentny_Pszczelarz/.venv/Lib/site-packages/tensorflow/python/util/decorator_utils.py
2023-06-19 00:49:18 +02:00

204 lines
5.8 KiB
Python

# Copyright 2016 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.
# ==============================================================================
"""Utility functions for writing decorators (which modify docstrings)."""
import sys
def get_qualified_name(function):
# Python 3
if hasattr(function, '__qualname__'):
return function.__qualname__
# Python 2
if hasattr(function, 'im_class'):
return function.im_class.__name__ + '.' + function.__name__
return function.__name__
def _normalize_docstring(docstring):
"""Normalizes the docstring.
Replaces tabs with spaces, removes leading and trailing blanks lines, and
removes any indentation.
Copied from PEP-257:
https://www.python.org/dev/peps/pep-0257/#handling-docstring-indentation
Args:
docstring: the docstring to normalize
Returns:
The normalized docstring
"""
if not docstring:
return ''
# Convert tabs to spaces (following the normal Python rules)
# and split into a list of lines:
lines = docstring.expandtabs().splitlines()
# Determine minimum indentation (first line doesn't count):
# (we use sys.maxsize because sys.maxint doesn't exist in Python 3)
indent = sys.maxsize
for line in lines[1:]:
stripped = line.lstrip()
if stripped:
indent = min(indent, len(line) - len(stripped))
# Remove indentation (first line is special):
trimmed = [lines[0].strip()]
if indent < sys.maxsize:
for line in lines[1:]:
trimmed.append(line[indent:].rstrip())
# Strip off trailing and leading blank lines:
while trimmed and not trimmed[-1]:
trimmed.pop()
while trimmed and not trimmed[0]:
trimmed.pop(0)
# Return a single string:
return '\n'.join(trimmed)
def add_notice_to_docstring(doc,
instructions,
no_doc_str,
suffix_str,
notice,
notice_type='Warning'):
"""Adds a deprecation notice to a docstring.
Args:
doc: The original docstring.
instructions: A string, describing how to fix the problem.
no_doc_str: The default value to use for `doc` if `doc` is empty.
suffix_str: Is added to the end of the first line.
notice: A list of strings. The main notice warning body.
notice_type: The type of notice to use. Should be one of `[Caution,
Deprecated, Important, Note, Warning]`
Returns:
A new docstring, with the notice attached.
Raises:
ValueError: If `notice` is empty.
"""
allowed_notice_types = ['Deprecated', 'Warning', 'Caution', 'Important',
'Note']
if notice_type not in allowed_notice_types:
raise ValueError(
f'Unrecognized notice type. Should be one of: {allowed_notice_types}')
if not doc:
lines = [no_doc_str]
else:
lines = _normalize_docstring(doc).splitlines()
lines[0] += ' ' + suffix_str
if not notice:
raise ValueError('The `notice` arg must not be empty.')
notice[0] = f'{notice_type}: {notice[0]}'
notice = [''] + notice + ([instructions] if instructions else [])
if len(lines) > 1:
# Make sure that we keep our distance from the main body
if lines[1].strip():
notice.append('')
lines[1:1] = notice
else:
lines += notice
return '\n'.join(lines)
def validate_callable(func, decorator_name):
if not hasattr(func, '__call__'):
raise ValueError(
'%s is not a function. If this is a property, make sure'
' @property appears before @%s in your source code:'
'\n\n@property\n@%s\ndef method(...)' % (
func, decorator_name, decorator_name))
class classproperty(object): # pylint: disable=invalid-name
"""Class property decorator.
Example usage:
class MyClass(object):
@classproperty
def value(cls):
return '123'
> print MyClass.value
123
"""
def __init__(self, func):
self._func = func
def __get__(self, owner_self, owner_cls):
return self._func(owner_cls)
class _CachedClassProperty(object):
"""Cached class property decorator.
Transforms a class method into a property whose value is computed once
and then cached as a normal attribute for the life of the class. Example
usage:
>>> class MyClass(object):
... @cached_classproperty
... def value(cls):
... print("Computing value")
... return '<property of %s>' % cls.__name__
>>> class MySubclass(MyClass):
... pass
>>> MyClass.value
Computing value
'<property of MyClass>'
>>> MyClass.value # uses cached value
'<property of MyClass>'
>>> MySubclass.value
Computing value
'<property of MySubclass>'
This decorator is similar to `functools.cached_property`, but it adds a
property to the class, not to individual instances.
"""
def __init__(self, func):
self._func = func
self._cache = {}
def __get__(self, obj, objtype):
if objtype not in self._cache:
self._cache[objtype] = self._func(objtype)
return self._cache[objtype]
def __set__(self, obj, value):
raise AttributeError('property %s is read-only' % self._func.__name__)
def __delete__(self, obj):
raise AttributeError('property %s is read-only' % self._func.__name__)
def cached_classproperty(func):
return _CachedClassProperty(func)
cached_classproperty.__doc__ = _CachedClassProperty.__doc__