def deprecatedProperty(version, replacement=None):
    """
    Return a decorator that marks a property as deprecated. To deprecate a
    regular callable or class, see L{deprecated}.

    @type version: L{incremental.Version}
    @param version: The version in which the callable will be marked as
        having been deprecated.  The decorated function will be annotated
        with this version, having it set as its C{deprecatedVersion}
        attribute.

    @param version: the version that the callable was deprecated in.
    @type version: L{incremental.Version}

    @param replacement: what should be used in place of the callable.
        Either pass in a string, which will be inserted into the warning
        message, or a callable, which will be expanded to its full import
        path.
    @type replacement: C{str} or callable

    @return: A new property with deprecated setter and getter.
    @rtype: C{property}

    @since: 16.1.0
    """

    class _DeprecatedProperty(property):
        """
        Extension of the build-in property to allow deprecated setters.
        """

        def _deprecatedWrapper(self, function):
            @wraps(function)
            def deprecatedFunction(*args, **kwargs):
                warn(
                    self.warningString,
                    DeprecationWarning,
                    stacklevel=2)
                return function(*args, **kwargs)
            return deprecatedFunction


        def setter(self, function):
            return property.setter(self, self._deprecatedWrapper(function))


    def deprecationDecorator(function):
        if _PY3:
            warningString = getDeprecationWarningString(
                function, version, None, replacement)
        else:
            # Because Python 2 sucks, we need to implement our own here -- lack
            # of __qualname__ means that we kinda have to stack walk. It maybe
            # probably works. Probably. -Amber
            functionName = function.__name__
            className = inspect.stack()[1][3]  # wow hax
            moduleName = function.__module__

            fqdn = "%s.%s.%s" % (moduleName, className, functionName)

            warningString = _getDeprecationWarningString(
                fqdn, version, None, replacement)

        @wraps(function)
        def deprecatedFunction(*args, **kwargs):
            warn(
                warningString,
                DeprecationWarning,
                stacklevel=2)
            return function(*args, **kwargs)

        _appendToDocstring(deprecatedFunction,
                           _getDeprecationDocstring(version, replacement))
        deprecatedFunction.deprecatedVersion = version

        result = _DeprecatedProperty(deprecatedFunction)
        result.warningString = warningString
        return result

    return deprecationDecorator

    Return a decorator that marks a property as deprecated. To deprecate a
    regular callable or class, see L{deprecated}.

    @type version: L{incremental.Version}
    @param version: The version in which the callable will be marked as
        having been deprecated.  The decorated function will be annotated
        with this version, having it set as its C{deprecatedVersion}
        attribute.

    @param version: the version that the callable was deprecated in.
    @type version: L{incremental.Version}

    @param replacement: what should be used in place of the callable.
        Either pass in a string, which will be inserted into the warning
        message, or a callable, which will be expanded to its full import
        path.
    @type replacement: C{str} or callable

    @return: A new property with deprecated setter and getter.
    @rtype: C{property}

    @since: 16.1.0
    
stackoverflow/venv/lib/python3.6/site-packages/twisted/python/deprecate.py