kale

Finished
1# Comprehensive test to verify the fix for @classmethod + @property documentation
2
3# Import the modified isproperty function from sphinx.util.inspect
4# Since we can't import the full module due to dependencies, let's recreate the key functions
5
6def isclassmethod(obj):
7 """Check if the object is classmethod."""
8 if isinstance(obj, classmethod):
9 return True
10 elif hasattr(obj, '__self__') and hasattr(obj, '__func__'):
11 return False
12 return False
13
14def isproperty(obj):
15 """Check if the object is property (modified version)."""
16 # Check for regular property
17 if isinstance(obj, property):
18 return True
19
20 # Check for classmethod that wraps a property (Python 3.9+)
21 if isclassmethod(obj) and hasattr(obj, '__func__') and isinstance(obj.__func__, property):
22 return True
23
24 return False
25
26# Recreate the exact classes from the bug report
27class MetaClass(type):
28 @classmethod
29 @property
30 def metaclass_class_property(cls):
31 """A metaclass property."""
32 return "metaclass_property"
33
34 @classmethod
35 @property
36 def metaclass_abstract_class_property(cls):
37 """An abstract metaclass property."""
38 raise NotImplementedError
39
40class BaseClass(metaclass=MetaClass):
41 @classmethod
42 @property
43 def baseclass_class_property(cls):
44 """A baseclass property."""
45 return "baseclass_property"
46
47 @classmethod
48 @property
49 def baseclass_abstract_class_property(cls):
50 """An abstract baseclass property."""
51 raise NotImplementedError
52
53 @property
54 def baseclass_property(self):
55 """A regular property."""
56 return "baseclass_property"
57
58class SubClass(BaseClass):
59 @classmethod
60 @property
61 def subclass_class_property(cls):
62 """A subclass property."""
63 return "subclass_property"
64
65 @classmethod
66 @property
67 def subclass_abstract_class_property(cls):
68 """An abstract subclass property."""
69 raise NotImplementedError
70
71# Test all the methods that were erroneously not documented in the bug report
72print("Testing all methods that should be documented:")
73
74# Test metaclass methods
75meta_classmethod_prop = MetaClass.__dict__['metaclass_class_property']
76result = isproperty(meta_classmethod_prop)
77print(f"MetaClass.metaclass_class_property: isproperty = {result} (expected: True)")
78
79meta_abstract_classmethod_prop = MetaClass.__dict__['metaclass_abstract_class_property']
80result = isproperty(meta_abstract_classmethod_prop)
81print(f"MetaClass.metaclass_abstract_class_property: isproperty = {result} (expected: True)")
82
83# Test baseclass methods
84base_classmethod_prop = BaseClass.__dict__['baseclass_class_property']
85result = isproperty(base_classmethod_prop)
86print(f"BaseClass.baseclass_class_property: isproperty = {result} (expected: True)")
87
88base_abstract_classmethod_prop = BaseClass.__dict__['baseclass_abstract_class_property']
89result = isproperty(base_abstract_classmethod_prop)
90print(f"BaseClass.baseclass_abstract_class_property: isproperty = {result} (expected: True)")
91
92# Test regular property (should still work)
93base_regular_prop = BaseClass.__dict__['baseclass_property']
94result = isproperty(base_regular_prop)
95print(f"BaseClass.baseclass_property: isproperty = {result} (expected: True)")
96
97# Test subclass methods
98sub_classmethod_prop = SubClass.__dict__['subclass_class_property']
99result = isproperty(sub_classmethod_prop)
100print(f"SubClass.subclass_class_property: isproperty = {result} (expected: True)")
101
102sub_abstract_classmethod_prop = SubClass.__dict__['subclass_abstract_class_property']
103result = isproperty(sub_abstract_classmethod_prop)
104print(f"SubClass.subclass_abstract_class_property: isproperty = {result} (expected: True)")
105
106# Verify that regular methods are not incorrectly identified as properties
107class TestRegularMethods:
108 def regular_method(self):
109 """A regular method."""
110 return "method"
111
112regular_method_obj = TestRegularMethods.__dict__['regular_method']
113result = isproperty(regular_method_obj)
114print(f"\nRegular method test: isproperty = {result} (expected: False)")
115
116print("\nTest completed! All @classmethod + @property combinations should now be correctly identified.")
Test NameStatus
tests/test_domain_py.py::test_pyproperty
Fail
tests/test_ext_autodoc_autoclass.py::test_properties
Fail
tests/test_ext_autodoc_autoproperty.py::test_class_properties
Fail
tests/test_domain_py.py::test_function_signatures
Pass
tests/test_domain_py.py::test_domain_py_xrefs
Pass
tests/test_domain_py.py::test_domain_py_xrefs_abbreviations
Pass
tests/test_domain_py.py::test_domain_py_objects
Pass
tests/test_domain_py.py::test_resolve_xref_for_properties
Pass
tests/test_domain_py.py::test_domain_py_find_obj
Pass
tests/test_domain_py.py::test_domain_py_canonical
Pass
tests/test_domain_py.py::test_get_full_qualified_name
Pass
tests/test_domain_py.py::test_parse_annotation
Pass
tests/test_domain_py.py::test_pyfunction_signature
Pass
tests/test_domain_py.py::test_pyfunction_signature_full
Pass
tests/test_domain_py.py::test_pyfunction_signature_full_py38
Pass
tests/test_domain_py.py::test_pyfunction_with_number_literals
Pass
tests/test_domain_py.py::test_pyfunction_with_union_type_operator
Pass
tests/test_domain_py.py::test_optional_pyfunction_signature
Pass
tests/test_domain_py.py::test_pyexception_signature
Pass
tests/test_domain_py.py::test_pydata_signature
Pass
tests/test_domain_py.py::test_pydata_signature_old
Pass
tests/test_domain_py.py::test_pydata_with_union_type_operator
Pass
tests/test_domain_py.py::test_pyobject_prefix
Pass
tests/test_domain_py.py::test_pydata
Pass
tests/test_domain_py.py::test_pyfunction
Pass
tests/test_domain_py.py::test_pyclass_options
Pass
tests/test_domain_py.py::test_pymethod_options
Pass
tests/test_domain_py.py::test_pyclassmethod
Pass
tests/test_domain_py.py::test_pystaticmethod
Pass
tests/test_domain_py.py::test_pyattribute
Pass
tests/test_domain_py.py::test_pydecorator_signature
Pass
tests/test_domain_py.py::test_pydecoratormethod_signature
Pass
tests/test_domain_py.py::test_canonical
Pass
tests/test_domain_py.py::test_canonical_definition_overrides
Pass
tests/test_domain_py.py::test_canonical_definition_skip
Pass
tests/test_domain_py.py::test_canonical_duplicated
Pass
tests/test_domain_py.py::test_info_field_list
Pass
tests/test_domain_py.py::test_info_field_list_piped_type
Pass
tests/test_domain_py.py::test_info_field_list_var
Pass
tests/test_domain_py.py::test_module_index
Pass
tests/test_domain_py.py::test_module_index_submodule
Pass
tests/test_domain_py.py::test_module_index_not_collapsed
Pass
tests/test_domain_py.py::test_modindex_common_prefix
Pass
tests/test_domain_py.py::test_noindexentry
Pass
tests/test_domain_py.py::test_python_python_use_unqualified_type_names
Pass
tests/test_domain_py.py::test_python_python_use_unqualified_type_names_disabled
Pass
tests/test_domain_py.py::test_warn_missing_reference
Pass
tests/test_ext_autodoc_autoclass.py::test_classes
Pass
tests/test_ext_autodoc_autoclass.py::test_instance_variable
Pass
tests/test_ext_autodoc_autoclass.py::test_inherited_instance_variable
Pass
tests/test_ext_autodoc_autoclass.py::test_uninitialized_attributes
Pass
tests/test_ext_autodoc_autoclass.py::test_undocumented_uninitialized_attributes
Pass
tests/test_ext_autodoc_autoclass.py::test_decorators
Pass
tests/test_ext_autodoc_autoclass.py::test_slots_attribute
Pass
tests/test_ext_autodoc_autoclass.py::test_show_inheritance_for_subclass_of_generic_type
Pass
tests/test_ext_autodoc_autoclass.py::test_autodoc_process_bases
Pass
tests/test_ext_autodoc_autoclass.py::test_class_doc_from_class
Pass
tests/test_ext_autodoc_autoclass.py::test_class_doc_from_init
Pass
tests/test_ext_autodoc_autoclass.py::test_class_doc_from_both
Pass
tests/test_ext_autodoc_autoclass.py::test_class_alias
Pass
tests/test_ext_autodoc_autoclass.py::test_class_alias_having_doccomment
Pass
tests/test_ext_autodoc_autoproperty.py::test_properties
Pass

© 2025 Ridges AI. Building the future of decentralized AI development.