summaryrefslogtreecommitdiff
path: root/sphinx/util/inspect.py
diff options
context:
space:
mode:
authorTakeshi KOMIYA <i.tkomiya@gmail.com>2019-04-13 23:13:00 +0900
committerTakeshi KOMIYA <i.tkomiya@gmail.com>2019-04-14 02:16:17 +0900
commitd41cae328ec139b4d65b60041f561657cfef86ab (patch)
tree8fc874bde6b39f7708877867f1bf3089d8cccdb9 /sphinx/util/inspect.py
parent91fac1a0c3d25f0ca1c35eed266877000936b1a2 (diff)
downloadsphinx-git-d41cae328ec139b4d65b60041f561657cfef86ab.tar.gz
Add sphinx.util.inspect:isattributedescriptor()
Diffstat (limited to 'sphinx/util/inspect.py')
-rw-r--r--sphinx/util/inspect.py39
1 files changed, 39 insertions, 0 deletions
diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py
index 0cf7c1084..877f727d4 100644
--- a/sphinx/util/inspect.py
+++ b/sphinx/util/inspect.py
@@ -29,6 +29,17 @@ if False:
# For type annotation
from typing import Any, Callable, Mapping, List, Tuple, Type # NOQA
+if sys.version_info > (3, 7):
+ from types import (
+ ClassMethodDescriptorType,
+ MethodDescriptorType,
+ WrapperDescriptorType
+ )
+else:
+ ClassMethodDescriptorType = type(object.__init__)
+ MethodDescriptorType = type(str.join)
+ WrapperDescriptorType = type(dict.__dict__['fromkeys'])
+
logger = logging.getLogger(__name__)
memory_address_re = re.compile(r' at 0x[0-9a-f]{8,16}(?=>)', re.IGNORECASE)
@@ -161,6 +172,34 @@ def isdescriptor(x):
return False
+def isattributedescriptor(obj):
+ # type: (Any) -> bool
+ """Check if the object is an attribute like descriptor."""
+ if inspect.isdatadescriptor(object):
+ # data descriptor is kind of attribute
+ return True
+ elif isdescriptor(obj):
+ # non data descriptor
+ if isfunction(obj) or isbuiltin(obj) or inspect.ismethod(obj):
+ # attribute must not be either function, builtin and method
+ return False
+ elif inspect.isclass(obj):
+ # attribute must not be a class
+ return False
+ elif isinstance(obj, (ClassMethodDescriptorType,
+ MethodDescriptorType,
+ WrapperDescriptorType)):
+ # attribute must not be a method descriptor
+ return False
+ elif type(obj).__name__ == "instancemethod":
+ # attribute must not be an instancemethod (C-API)
+ return False
+ else:
+ return True
+ else:
+ return False
+
+
def isfunction(obj):
# type: (Any) -> bool
"""Check if the object is function."""