def __getitem__(self, key):
        """Bit slicing.

        Selects a constant-width, constant-offset part of :py:`self`. All three slicing syntaxes
        (:py:`self[i]`, :py:`self[i:j]`, and :py:`self[i:j:k]`) as well as negative indices are
        supported. Like with other Python containers, out-of-bounds indices are trimmed to
        the bounds of :py:`self`.

        To select a variable-offset part of :py:`self`, use :meth:`bit_select` or
        :meth:`word_select` instead.

        Returns
        -------
        :class:`Value`, :py:`unsigned(1)`, :ref:`assignable <lang-assignable>`
            If :py:`key` is an :class:`int`.
        :class:`Value`, :py:`unsigned(j - i)`, :ref:`assignable <lang-assignable>`
            If :py:`key` is a slice :py:`i:j` where :py:`i` and :py:`j` are :class:`int`\\ s.
        :class:`Value`, :py:`unsigned(len(range(*slice(i, j, k).indices(len(self)))))`, :ref:`assignable <lang-assignable>`
            If :py:`key` is a slice :py:`i:j:k` where :py:`i`, :py:`j`, and :py:`k` are :class:`int`\\ s.
        """
        length = len(self)
        if isinstance(key, int):
            if key not in range(-length, length):
                raise IndexError(f"Index {key} is out of bounds for a {length}-bit value")
            if key < 0:
                key += length
            return Slice(self, key, key + 1, src_loc_at=1)
        elif isinstance(key, slice):
            if isinstance(key.start, Value) or isinstance(key.stop, Value):
                raise TypeError(f"Cannot slice value with a value; use Value.bit_select() or "
                                f"Value.word_select() instead")
            start, stop, step = key.indices(length)
            if step != 1:
                return Cat(self[i] for i in range(start, stop, step))
            return Slice(self, start, stop, src_loc_at=1)
        elif isinstance(key, Value):
            raise TypeError(f"Cannot index value with a value; use Value.bit_select() instead")
        else:
            raise TypeError(f"Cannot index value with {key!r}")
Bit slicing.

        Selects a constant-width, constant-offset part of :py:`self`. All three slicing syntaxes
        (:py:`self[i]`, :py:`self[i:j]`, and :py:`self[i:j:k]`) as well as negative indices are
        supported. Like with other Python containers, out-of-bounds indices are trimmed to
        the bounds of :py:`self`.

        To select a variable-offset part of :py:`self`, use :meth:`bit_select` or
        :meth:`word_select` instead.

        Returns
        -------
        :class:`Value`, :py:`unsigned(1)`, :ref:`assignable <lang-assignable>`
            If :py:`key` is an :class:`int`.
        :class:`Value`, :py:`unsigned(j - i)`, :ref:`assignable <lang-assignable>`
            If :py:`key` is a slice :py:`i:j` where :py:`i` and :py:`j` are :class:`int`\ s.
        :class:`Value`, :py:`unsigned(len(range(*slice(i, j, k).indices(len(self)))))`, :ref:`assignable <lang-assignable>`
            If :py:`key` is a slice :py:`i:j:k` where :py:`i`, :py:`j`, and :py:`k` are :class:`int`\ s.
        
amaranth/hdl/_ast.py