# Test case for property
# more tests are in test_descr

import sys
import unittest
from test import support

class PropertyBase(Exception):
    pass

class PropertyGet(PropertyBase):
    pass

class PropertySet(PropertyBase):
    pass

class PropertyDel(PropertyBase):
    pass

class BaseClass(object):
    def __init__(self):
        self._spam = 5

    @property
    def spam(self):
        """BaseClass.getter"""
        return self._spam

    @spam.setter
    def spam(self, value):
        self._spam = value

    @spam.deleter
    def spam(self):
        del self._spam

class SubClass(BaseClass):

    @BaseClass.spam.getter
    def spam(self):
        """SubClass.getter"""
        raise PropertyGet(self._spam)

    @spam.setter
    def spam(self, value):
        raise PropertySet(self._spam)

    @spam.deleter
    def spam(self):
        raise PropertyDel(self._spam)

class PropertyDocBase(object):
    _spam = 1
    def _get_spam(self):
        return self._spam
    spam = property(_get_spam, doc="spam spam spam")

class PropertyDocSub(PropertyDocBase):
    @PropertyDocBase.spam.getter
    def spam(self):
        """The decorator does not use this doc string"""
        return self._spam

class PropertySubNewGetter(BaseClass):
    @BaseClass.spam.getter
    def spam(self):
        """new docstring"""
        return 5

class PropertyNewGetter(object):
    @property
    def spam(self):
        """original docstring"""
        return 1
    @spam.getter
    def spam(self):
        """new docstring"""
        return 8

class PropertyTests(unittest.TestCase):
    def test_property_decorator_baseclass(self):
        # see #1620
        base = BaseClass()
        self.assertEqual(base.spam, 5)
        self.assertEqual(base._spam, 5)
        base.spam = 10
        self.assertEqual(base.spam, 10)
        self.assertEqual(base._spam, 10)
        delattr(base, "spam")
        self.assertTrue(not hasattr(base, "spam"))
        self.assertTrue(not hasattr(base, "_spam"))
        base.spam = 20
        self.assertEqual(base.spam, 20)
        self.assertEqual(base._spam, 20)

    def test_property_decorator_subclass(self):
        # see #1620
        sub = SubClass()
        self.assertRaises(PropertyGet, getattr, sub, "spam")
        self.assertRaises(PropertySet, setattr, sub, "spam", None)
        self.assertRaises(PropertyDel, delattr, sub, "spam")

    @unittest.skipIf(sys.flags.optimize >= 2,
                     "Docstrings are omitted with -O2 and above")
    def test_property_decorator_subclass_doc(self):
        sub = SubClass()
        self.assertEqual(sub.__class__.spam.__doc__, "SubClass.getter")

    @unittest.skipIf(sys.flags.optimize >= 2,
                     "Docstrings are omitted with -O2 and above")
    def test_property_decorator_baseclass_doc(self):
        base = BaseClass()
        self.assertEqual(base.__class__.spam.__doc__, "BaseClass.getter")

    def test_property_decorator_doc(self):
        base = PropertyDocBase()
        sub = PropertyDocSub()
        self.assertEqual(base.__class__.spam.__doc__, "spam spam spam")
        self.assertEqual(sub.__class__.spam.__doc__, "spam spam spam")

    @unittest.skipIf(sys.flags.optimize >= 2,
                     "Docstrings are omitted with -O2 and above")
    def test_property_getter_doc_override(self):
        newgettersub = PropertySubNewGetter()
        self.assertEqual(newgettersub.spam, 5)
        self.assertEqual(newgettersub.__class__.spam.__doc__, "new docstring")
        newgetter = PropertyNewGetter()
        self.assertEqual(newgetter.spam, 8)
        self.assertEqual(newgetter.__class__.spam.__doc__, "new docstring")

    def test_property___isabstractmethod__descriptor(self):
        for val in (True, False, [], [1], '', '1'):
            class C(object):
                def foo(self):
                    pass
                foo.__isabstractmethod__ = val
                foo = property(foo)
            self.assertIs(C.foo.__isabstractmethod__, bool(val))

        # check that the property's __isabstractmethod__ descriptor does the
        # right thing when presented with a value that fails truth testing:
        class NotBool(object):
            def __bool__(self):
                raise ValueError()
            __len__ = __bool__
        with self.assertRaises(ValueError):
            class C(object):
                def foo(self):
                    pass
                foo.__isabstractmethod__ = NotBool()
                foo = property(foo)
            C.foo.__isabstractmethod__

    @unittest.skipIf(sys.flags.optimize >= 2,
                     "Docstrings are omitted with -O2 and above")
    def test_property_builtin_doc_writable(self):
        p = property(doc='basic')
        self.assertEqual(p.__doc__, 'basic')
        p.__doc__ = 'extended'
        self.assertEqual(p.__doc__, 'extended')

    @unittest.skipIf(sys.flags.optimize >= 2,
                     "Docstrings are omitted with -O2 and above")
    def test_property_decorator_doc_writable(self):
        class PropertyWritableDoc(object):

            @property
            def spam(self):
                """Eggs"""
                return "eggs"

        sub = PropertyWritableDoc()
        self.assertEqual(sub.__class__.spam.__doc__, 'Eggs')
        sub.__class__.spam.__doc__ = 'Spam'
        self.assertEqual(sub.__class__.spam.__doc__, 'Spam')

    @support.refcount_test
    def test_refleaks_in___init__(self):
        gettotalrefcount = support.get_attribute(sys, 'gettotalrefcount')
        fake_prop = property('fget', 'fset', 'fdel', 'doc')
        refs_before = gettotalrefcount()
        for i in range(100):
            fake_prop.__init__('fget', 'fset', 'fdel', 'doc')
        self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10)

    @support.refcount_test
    def test_gh_115618(self):
        # Py_XDECREF() was improperly called for None argument
        # in property methods.
        gettotalrefcount = support.get_attribute(sys, 'gettotalrefcount')
        prop = property()
        refs_before = gettotalrefcount()
        for i in range(100):
            prop = prop.getter(None)
        self.assertIsNone(prop.fget)
        for i in range(100):
            prop = prop.setter(None)
        self.assertIsNone(prop.fset)
        for i in range(100):
            prop = prop.deleter(None)
        self.assertIsNone(prop.fdel)
        self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10)

    def test_property_name(self):
        def getter(self):
            return 42

        def setter(self, value):
            pass

        class A:
            @property
            def foo(self):
                return 1

            @foo.setter
            def oof(self, value):
                pass

            bar = property(getter)
            baz = property(None, setter)

        self.assertEqual(A.foo.__name__, 'foo')
        self.assertEqual(A.oof.__name__, 'oof')
        self.assertEqual(A.bar.__name__, 'bar')
        self.assertEqual(A.baz.__name__, 'baz')

        A.quux = property(getter)
        self.assertEqual(A.quux.__name__, 'getter')
        A.quux.__name__ = 'myquux'
        self.assertEqual(A.quux.__name__, 'myquux')
        self.assertEqual(A.bar.__name__, 'bar')  # not affected
        A.quux.__name__ = None
        self.assertIsNone(A.quux.__name__)

        with self.assertRaisesRegex(
            AttributeError, "'property' object has no attribute '__name__'"
        ):
            property(None, setter).__name__

        with self.assertRaisesRegex(
            AttributeError, "'property' object has no attribute '__name__'"
        ):
            property(1).__name__

        class Err:
            def __getattr__(self, attr):
                raise RuntimeError('fail')

        p = property(Err())
        with self.assertRaisesRegex(RuntimeError, 'fail'):
            p.__name__

        p.__name__ = 'not_fail'
        self.assertEqual(p.__name__, 'not_fail')

    def test_property_set_name_incorrect_args(self):
        p = property()

        for i in (0, 1, 3):
            with self.assertRaisesRegex(
                TypeError,
                fr'^__set_name__\(\) takes 2 positional arguments but {i} were given$'
            ):
                p.__set_name__(*([0] * i))

    def test_property_setname_on_property_subclass(self):
        # https://github.com/python/cpython/issues/100942
        # Copy was setting the name field without first
        # verifying that the copy was an actual property
        # instance.  As a result, the code below was
        # causing a segfault.

        class pro(property):
            def __new__(typ, *args, **kwargs):
                return "abcdef"

        class A:
            pass

        p = property.__new__(pro)
        p.__set_name__(A, 1)
        np = p.getter(lambda self: 1)

# Issue 5890: subclasses of property do not preserve method __doc__ strings
class PropertySub(property):
    """This is a subclass of property"""

class PropertySubWoDoc(property):
    pass

class PropertySubSlots(property):
    """This is a subclass of property that defines __slots__"""
    __slots__ = ()

class PropertySubclassTests(unittest.TestCase):

    @support.requires_docstrings
    def test_slots_docstring_copy_exception(self):
        # A special case error that we preserve despite the GH-98963 behavior
        # that would otherwise silently ignore this error.
        # This came from commit b18500d39d791c879e9904ebac293402b4a7cd34
        # as part of https://bugs.python.org/issue5890 which allowed docs to
        # be set via property subclasses in the first place.
        with self.assertRaises(AttributeError):
            class Foo(object):
                @PropertySubSlots
                def spam(self):
                    """Trying to copy this docstring will raise an exception"""
                    return 1

    def test_property_with_slots_no_docstring(self):
        # https://github.com/python/cpython/issues/98963#issuecomment-1574413319
        class slotted_prop(property):
            __slots__ = ("foo",)

        p = slotted_prop()  # no AttributeError
        self.assertIsNone(getattr(p, "__doc__", None))

        def undocumented_getter():
            return 4

        p = slotted_prop(undocumented_getter)  # New in 3.12: no AttributeError
        self.assertIsNone(getattr(p, "__doc__", None))

    @unittest.skipIf(sys.flags.optimize >= 2,
                     "Docstrings are omitted with -O2 and above")
    def test_property_with_slots_docstring_silently_dropped(self):
        # https://github.com/python/cpython/issues/98963#issuecomment-1574413319
        class slotted_prop(property):
            __slots__ = ("foo",)

        p = slotted_prop(doc="what's up")  # no AttributeError
        self.assertIsNone(p.__doc__)

        def documented_getter():
            """getter doc."""
            return 4

        # Historical behavior: A docstring from a getter always raises.
        # (matches test_slots_docstring_copy_exception above).
        with self.assertRaises(AttributeError):
            p = slotted_prop(documented_getter)

    @unittest.skipIf(sys.flags.optimize >= 2,
                     "Docstrings are omitted with -O2 and above")
    def test_property_with_slots_and_doc_slot_docstring_present(self):
        # https://github.com/python/cpython/issues/98963#issuecomment-1574413319
        class slotted_prop(property):
            __slots__ = ("foo", "__doc__")

        p = slotted_prop(doc="what's up")
        self.assertEqual("what's up", p.__doc__)  # new in 3.12: This gets set.

        def documented_getter():
            """what's up getter doc?"""
            return 4

        p = slotted_prop(documented_getter)
        self.assertEqual("what's up getter doc?", p.__doc__)

    @unittest.skipIf(sys.flags.optimize >= 2,
                     "Docstrings are omitted with -O2 and above")
    def test_issue41287(self):

        self.assertEqual(PropertySub.__doc__, "This is a subclass of property",
                         "Docstring of `property` subclass is ignored")

        doc = PropertySub(None, None, None, "issue 41287 is fixed").__doc__
        self.assertEqual(doc, "issue 41287 is fixed",
                         "Subclasses of `property` ignores `doc` constructor argument")

        def getter(x):
            """Getter docstring"""

        def getter_wo_doc(x):
            pass

        for ps in property, PropertySub, PropertySubWoDoc:
            doc = ps(getter, None, None, "issue 41287 is fixed").__doc__
            self.assertEqual(doc, "issue 41287 is fixed",
                             "Getter overrides explicit property docstring (%s)" % ps.__name__)

            doc = ps(getter, None, None, None).__doc__
            self.assertEqual(doc, "Getter docstring", "Getter docstring is not picked-up (%s)" % ps.__name__)

            doc = ps(getter_wo_doc, None, None, "issue 41287 is fixed").__doc__
            self.assertEqual(doc, "issue 41287 is fixed",
                             "Getter overrides explicit property docstring (%s)" % ps.__name__)

            doc = ps(getter_wo_doc, None, None, None).__doc__
            self.assertIsNone(doc, "Property class doc appears in instance __doc__ (%s)" % ps.__name__)

    @unittest.skipIf(sys.flags.optimize >= 2,
                     "Docstrings are omitted with -O2 and above")
    def test_docstring_copy(self):
        class Foo(object):
            @PropertySub
            def spam(self):
                """spam wrapped in property subclass"""
                return 1
        self.assertEqual(
            Foo.spam.__doc__,
            "spam wrapped in property subclass")

    @unittest.skipIf(sys.flags.optimize >= 2,
                     "Docstrings are omitted with -O2 and above")
    def test_docstring_copy2(self):
        """
        Property tries to provide the best docstring it finds for its instances.
        If a user-provided docstring is available, it is preserved on copies.
        If no docstring is available during property creation, the property
        will utilize the docstring from the getter if available.
        """
        def getter1(self):
            return 1
        def getter2(self):
            """doc 2"""
            return 2
        def getter3(self):
            """doc 3"""
            return 3

        # Case-1: user-provided doc is preserved in copies
        #         of property with undocumented getter
        p = property(getter1, None, None, "doc-A")

        p2 = p.getter(getter2)
        self.assertEqual(p.__doc__, "doc-A")
        self.assertEqual(p2.__doc__, "doc-A")

        # Case-2: user-provided doc is preserved in copies
        #         of property with documented getter
        p = property(getter2, None, None, "doc-A")

        p2 = p.getter(getter3)
        self.assertEqual(p.__doc__, "doc-A")
        self.assertEqual(p2.__doc__, "doc-A")

        # Case-3: with no user-provided doc new getter doc
        #         takes precedence
        p = property(getter2, None, None, None)

        p2 = p.getter(getter3)
        self.assertEqual(p.__doc__, "doc 2")
        self.assertEqual(p2.__doc__, "doc 3")

        # Case-4: A user-provided doc is assigned after property construction
        #         with documented getter. The doc IS NOT preserved.
        #         It's an odd behaviour, but it's a strange enough
        #         use case with no easy solution.
        p = property(getter2, None, None, None)
        p.__doc__ = "user"
        p2 = p.getter(getter3)
        self.assertEqual(p.__doc__, "user")
        self.assertEqual(p2.__doc__, "doc 3")

        # Case-5: A user-provided doc is assigned after property construction
        #         with UNdocumented getter. The doc IS preserved.
        p = property(getter1, None, None, None)
        p.__doc__ = "user"
        p2 = p.getter(getter2)
        self.assertEqual(p.__doc__, "user")
        self.assertEqual(p2.__doc__, "user")

    @unittest.skipIf(sys.flags.optimize >= 2,
                     "Docstrings are omitted with -O2 and above")
    def test_prefer_explicit_doc(self):
        # Issue 25757: subclasses of property lose docstring
        self.assertEqual(property(doc="explicit doc").__doc__, "explicit doc")
        self.assertEqual(PropertySub(doc="explicit doc").__doc__, "explicit doc")

        class Foo:
            spam = PropertySub(doc="spam explicit doc")

            @spam.getter
            def spam(self):
                """ignored as doc already set"""
                return 1

            def _stuff_getter(self):
                """ignored as doc set directly"""
            stuff = PropertySub(doc="stuff doc argument", fget=_stuff_getter)

        #self.assertEqual(Foo.spam.__doc__, "spam explicit doc")
        self.assertEqual(Foo.stuff.__doc__, "stuff doc argument")

    def test_property_no_doc_on_getter(self):
        # If a property's getter has no __doc__ then the property's doc should
        # be None; test that this is consistent with subclasses as well; see
        # GH-2487
        class NoDoc:
            @property
            def __doc__(self):
                raise AttributeError

        self.assertEqual(property(NoDoc()).__doc__, None)
        self.assertEqual(PropertySub(NoDoc()).__doc__, None)

    @unittest.skipIf(sys.flags.optimize >= 2,
                     "Docstrings are omitted with -O2 and above")
    def test_property_setter_copies_getter_docstring(self):
        class Foo(object):
            def __init__(self): self._spam = 1
            @PropertySub
            def spam(self):
                """spam wrapped in property subclass"""
                return self._spam
            @spam.setter
            def spam(self, value):
                """this docstring is ignored"""
                self._spam = value
        foo = Foo()
        self.assertEqual(foo.spam, 1)
        foo.spam = 2
        self.assertEqual(foo.spam, 2)
        self.assertEqual(
            Foo.spam.__doc__,
            "spam wrapped in property subclass")
        class FooSub(Foo):
            @Foo.spam.setter
            def spam(self, value):
                """another ignored docstring"""
                self._spam = 'eggs'
        foosub = FooSub()
        self.assertEqual(foosub.spam, 1)
        foosub.spam = 7
        self.assertEqual(foosub.spam, 'eggs')
        self.assertEqual(
            FooSub.spam.__doc__,
            "spam wrapped in property subclass")

    @unittest.skipIf(sys.flags.optimize >= 2,
                     "Docstrings are omitted with -O2 and above")
    def test_property_new_getter_new_docstring(self):

        class Foo(object):
            @PropertySub
            def spam(self):
                """a docstring"""
                return 1
            @spam.getter
            def spam(self):
                """a new docstring"""
                return 2
        self.assertEqual(Foo.spam.__doc__, "a new docstring")
        class FooBase(object):
            @PropertySub
            def spam(self):
                """a docstring"""
                return 1
        class Foo2(FooBase):
            @FooBase.spam.getter
            def spam(self):
                """a new docstring"""
                return 2
        self.assertEqual(Foo.spam.__doc__, "a new docstring")


class _PropertyUnreachableAttribute:
    msg_format = None
    obj = None
    cls = None

    def _format_exc_msg(self, msg):
        return self.msg_format.format(msg)

    @classmethod
    def setUpClass(cls):
        cls.obj = cls.cls()

    def test_get_property(self):
        with self.assertRaisesRegex(AttributeError, self._format_exc_msg("has no getter")):
            self.obj.foo

    def test_set_property(self):
        with self.assertRaisesRegex(AttributeError, self._format_exc_msg("has no setter")):
            self.obj.foo = None

    def test_del_property(self):
        with self.assertRaisesRegex(AttributeError, self._format_exc_msg("has no deleter")):
            del self.obj.foo


class PropertyUnreachableAttributeWithName(_PropertyUnreachableAttribute, unittest.TestCase):
    msg_format = r"^property 'foo' of 'PropertyUnreachableAttributeWithName\.cls' object {}$"

    class cls:
        foo = property()


class PropertyUnreachableAttributeNoName(_PropertyUnreachableAttribute, unittest.TestCase):
    msg_format = r"^property of 'PropertyUnreachableAttributeNoName\.cls' object {}$"

    class cls:
        pass

    cls.foo = property()


if __name__ == '__main__':
    unittest.main()
