Update sentinel (#757)
diff --git a/doc/index.rst b/doc/index.rst
index e8da24d..8e577db 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -1075,12 +1075,12 @@
 Sentinel objects
 ~~~~~~~~~~~~~~~~
 
-.. class:: sentinel(name, /)
+.. class:: sentinel(name, /, *, repr=None)
 
    A type used to define sentinel values. The *name* argument should be the
    name of the variable to which the return value shall be assigned.
 
-   Assigning attributes to a sentinel is deprecated.
+   Assigning attributes to a sentinel is deprecated (except for __module__).
 
    Example::
 
@@ -1106,7 +1106,7 @@
       Now supports pickle and will be reduced as a singleton.
       Renamed from `Sentinel` to `sentinel`, `Sentinel` is deprecated.
       Automatic `repr` string no longer has angle brackets.
-      `repr` parameter was deprecated.
+      `repr` as a positional argument is deprecated.
       `name` as a keyword is deprecated.
       Subclassing and attribute assignment are deprecated.
 
diff --git a/src/test_typing_extensions.py b/src/test_typing_extensions.py
index 6dd0264..4149eeb 100644
--- a/src/test_typing_extensions.py
+++ b/src/test_typing_extensions.py
@@ -9619,10 +9619,18 @@
         self.assertEqual(sentinel_no_repr.__name__, 'sentinel_no_repr')
         self.assertEqual(repr(sentinel_no_repr), 'sentinel_no_repr')
 
+    @skipIf(TYPING_3_15_0, reason="'Passing 'repr' as a positional argument was removed in 3.15")
+    def test_sentinel_deprecated_argument_repr(self):
+        with self.assertWarnsRegex(DeprecationWarning, r"Passing 'repr' as a positional argument is deprecated; pass it by keyword instead."):
+            sentinel_argument_repr = sentinel('sentinel_argument_repr', 'argument_repr')
+
+        self.assertEqual(repr(sentinel_argument_repr), 'argument_repr')
+
     @skipIf(TYPING_3_15_0_BETA_1, reason="'repr' parameter is not yet available in 3.15.0b1")
-    def test_sentinel_explicit_repr(self):
-        sentinel_explicit_repr = sentinel('sentinel_explicit_repr', repr='explicit_repr')
-        self.assertEqual(repr(sentinel_explicit_repr), 'explicit_repr')
+    def test_sentinel_keyword_repr(self):
+        sentinel_keyword_repr = sentinel('sentinel_keyword_repr', repr='keyword_repr')
+
+        self.assertEqual(repr(sentinel_keyword_repr), 'keyword_repr')
 
     @skipIf(sys.version_info < (3, 10), reason='New unions not available in 3.9')
     def test_sentinel_type_expression_union(self):
@@ -9675,6 +9683,8 @@
             my_sentinel = Sentinel(name="my_sentinel")
         with self.assertWarnsRegex(DeprecationWarning, r"Setting attribute 'foo' on sentinel objects is deprecated"):
             my_sentinel.foo = "bar"
+        with self.assertWarnsRegex(DeprecationWarning, r"Setting attribute '__name__' on sentinel objects is deprecated"):
+            my_sentinel.__name__ = "bar"
 
     @skipUnless(TYPING_3_15_0, reason='Deprecated sentinel APIs are available before 3.15')
     def test_sentinel_removed_deprecated_apis(self):
@@ -9687,6 +9697,8 @@
             Sentinel(name="my_sentinel")
         with self.assertRaises(AttributeError):
             sentinel('my_sentinel').foo = "bar"
+        with self.assertRaises(AttributeError):
+            sentinel('my_sentinel').__name__ = "bar"
 
 
 def load_tests(loader, tests, pattern):
diff --git a/src/typing_extensions.py b/src/typing_extensions.py
index 31c37e5..64b2676 100644
--- a/src/typing_extensions.py
+++ b/src/typing_extensions.py
@@ -189,9 +189,10 @@
         def __init__(
             self,
             __name: str = _sentinel_placeholder,
+            __repr: typing.Optional[str] = _sentinel_placeholder,
             /,
-            repr: typing.Optional[str] = None,
             *,
+            repr: typing.Optional[str] = None,
             name: str = _sentinel_placeholder,
         ) -> None:
             if name is not _sentinel_placeholder:
@@ -204,8 +205,16 @@
                 __name = name
             if __name is _sentinel_placeholder:
                 raise TypeError("First parameter 'name' is required")
+            if __repr is not _sentinel_placeholder:
+                warnings.warn(
+                    "Passing 'repr' as a positional argument is deprecated; "
+                    "pass it by keyword instead.",
+                    DeprecationWarning,
+                    stacklevel=2,
+                )
+                repr = __repr
 
-            self.__name__ = __name
+            self._name = __name
             self._repr = repr if repr is not None else __name
 
             # For pickling as a singleton:
@@ -221,7 +230,7 @@
             super().__init_subclass__()
 
         def __setattr__(self, attr: str, value: object) -> None:
-            if attr not in {"__name__", "_repr", "__module__"}:
+            if attr not in {"_name", "_repr", "__module__"}:
                 warnings.warn(
                     f"Setting attribute {attr!r} on sentinel objects is deprecated "
                     "and will be disallowed in Python 3.15.",
@@ -230,7 +239,15 @@
                 )
             super().__setattr__(attr, value)
 
-        def __repr__(self):
+        @property
+        def __name__(self) -> str:
+            return self._name
+
+        @__name__.setter
+        def __name__(self, value: str) -> None:
+            self._name = value
+
+        def __repr__(self) -> str:
             return self._repr
 
         if sys.version_info < (3, 11):