diff --git a/black.py b/black.py
index 9938b37..910a0ed 100644
--- a/black.py
+++ b/black.py
@@ -143,6 +143,7 @@ class Feature(Enum):
     ASYNC_IDENTIFIERS = 6
     ASYNC_KEYWORDS = 7
     ASSIGNMENT_EXPRESSIONS = 8
+    POS_ONLY_ARGUMENTS = 9
 
 
 VERSION_TO_FEATURES: Dict[TargetVersion, Set[Feature]] = {
@@ -178,6 +179,7 @@ class Feature(Enum):
         Feature.TRAILING_COMMA_IN_DEF,
         Feature.ASYNC_KEYWORDS,
         Feature.ASSIGNMENT_EXPRESSIONS,
+        Feature.POS_ONLY_ARGUMENTS,
     },
 }
 
@@ -935,6 +937,7 @@ def show(cls, code: Union[str, Leaf, Node]) -> None:
     token.DOUBLESTAR,
 }
 STARS = {token.STAR, token.DOUBLESTAR}
+VARARGS_SPECIALS = STARS | {token.SLASH}
 VARARGS_PARENTS = {
     syms.arglist,
     syms.argument,  # double star in arglist
@@ -1847,7 +1850,7 @@ def whitespace(leaf: Leaf, *, complex_subscript: bool) -> str:  # noqa: C901
                     # that, too.
                     return prevp.prefix
 
-        elif prevp.type in STARS:
+        elif prevp.type in VARARGS_SPECIALS:
             if is_vararg(prevp, within=VARARGS_PARENTS | UNPACKING_PARENTS):
                 return NO
 
@@ -1937,7 +1940,7 @@ def whitespace(leaf: Leaf, *, complex_subscript: bool) -> str:  # noqa: C901
             if not prevp or prevp.type == token.LPAR:
                 return NO
 
-        elif prev.type in {token.EQUAL} | STARS:
+        elif prev.type in {token.EQUAL} | VARARGS_SPECIALS:
             return NO
 
     elif p.type == syms.decorator:
@@ -3086,7 +3089,7 @@ def is_vararg(leaf: Leaf, within: Set[NodeType]) -> bool:
     extended iterable unpacking (PEP 3132) and additional unpacking
     generalizations (PEP 448).
     """
-    if leaf.type not in STARS or not leaf.parent:
+    if leaf.type not in VARARGS_SPECIALS or not leaf.parent:
         return False
 
     p = leaf.parent
@@ -3201,8 +3204,9 @@ def get_features_used(node: Node) -> Set[Feature]:
 
     Currently looking for:
     - f-strings;
-    - underscores in numeric literals; and
-    - trailing commas after * or ** in function signatures and calls.
+    - underscores in numeric literals;
+    - trailing commas after * or ** in function signatures and calls;
+    - positional only arguments in function signatures and lambdas;
     """
     features: Set[Feature] = set()
     for n in node.pre_order():
@@ -3215,6 +3219,10 @@ def get_features_used(node: Node) -> Set[Feature]:
             if "_" in n.value:  # type: ignore
                 features.add(Feature.NUMERIC_UNDERSCORES)
 
+        elif n.type == token.SLASH:
+            if n.parent and n.parent.type in {syms.typedargslist, syms.arglist}:
+                features.add(Feature.POS_ONLY_ARGUMENTS)
+
         elif n.type == token.COLONEQUAL:
             features.add(Feature.ASSIGNMENT_EXPRESSIONS)
 
diff --git a/blib2to3/Grammar.txt b/blib2to3/Grammar.txt
index 1061ac8..daecb15 100644
--- a/blib2to3/Grammar.txt
+++ b/blib2to3/Grammar.txt
@@ -18,15 +18,55 @@ decorated: decorators (classdef | funcdef | async_funcdef)
 async_funcdef: ASYNC funcdef
 funcdef: 'def' NAME parameters ['->' test] ':' suite
 parameters: '(' [typedargslist] ')'
-typedargslist: ((tfpdef ['=' test] ',')*
-                ('*' [tname] (',' tname ['=' test])* [',' ['**' tname [',']]] | '**' tname [','])
-                | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])
+
+# The following definition for typedarglist is equivalent to this set of rules:
+#
+#     arguments = argument (',' argument)*
+#     argument = tfpdef ['=' test]
+#     kwargs = '**' tname [',']
+#     args = '*' [tname]
+#     kwonly_kwargs = (',' argument)* [',' [kwargs]]
+#     args_kwonly_kwargs = args kwonly_kwargs | kwargs
+#     poskeyword_args_kwonly_kwargs = arguments [',' [args_kwonly_kwargs]]
+#     typedargslist_no_posonly  = poskeyword_args_kwonly_kwargs | args_kwonly_kwargs
+#     typedarglist = arguments ',' '/' [',' [typedargslist_no_posonly]])|(typedargslist_no_posonly)"
+#
+# It needs to be fully expanded to allow our LL(1) parser to work on it.
+
+typedargslist: tfpdef ['=' test] (',' tfpdef ['=' test])* ',' '/' [
+                     ',' [((tfpdef ['=' test] ',')* ('*' [tname] (',' tname ['=' test])*
+                            [',' ['**' tname [',']]] | '**' tname [','])
+                     | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])]
+                ] | ((tfpdef ['=' test] ',')* ('*' [tname] (',' tname ['=' test])*
+                     [',' ['**' tname [',']]] | '**' tname [','])
+                     | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])
+
 tname: NAME [':' test]
 tfpdef: tname | '(' tfplist ')'
 tfplist: tfpdef (',' tfpdef)* [',']
-varargslist: ((vfpdef ['=' test] ',')*
-              ('*' [vname] (',' vname ['=' test])*  [',' ['**' vname [',']]] | '**' vname [','])
-              | vfpdef ['=' test] (',' vfpdef ['=' test])* [','])
+
+# The following definition for varargslist is equivalent to this set of rules:
+#
+#     arguments = argument (',' argument )*
+#     argument = vfpdef ['=' test]
+#     kwargs = '**' vname [',']
+#     args = '*' [vname]
+#     kwonly_kwargs = (',' argument )* [',' [kwargs]]
+#     args_kwonly_kwargs = args kwonly_kwargs | kwargs
+#     poskeyword_args_kwonly_kwargs = arguments [',' [args_kwonly_kwargs]]
+#     vararglist_no_posonly = poskeyword_args_kwonly_kwargs | args_kwonly_kwargs
+#     varargslist = arguments ',' '/' [','[(vararglist_no_posonly)]] | (vararglist_no_posonly)
+#
+# It needs to be fully expanded to allow our LL(1) parser to work on it.
+
+varargslist: vfpdef ['=' test ](',' vfpdef ['=' test])* ',' '/' [',' [
+                     ((vfpdef ['=' test] ',')* ('*' [vname] (',' vname ['=' test])*
+                            [',' ['**' vname [',']]] | '**' vname [','])
+                            | vfpdef ['=' test] (',' vfpdef ['=' test])* [','])
+                     ]] | ((vfpdef ['=' test] ',')*
+                     ('*' [vname] (',' vname ['=' test])*  [',' ['**' vname [',']]]| '**' vname [','])
+                     | vfpdef ['=' test] (',' vfpdef ['=' test])* [','])
+
 vname: NAME
 vfpdef: vname | '(' vfplist ')'
 vfplist: vfpdef (',' vfpdef)* [',']

Support PEP-570 - positional only arguments
https://www.python.org/dev/peps/pep-0570/

This might complicate our Grammar quite a bit: https://github.com/python/cpython/blob/8c77b8cb9188165a123f2512026e3629bf03dc9b/Grammar/Grammar#L40-L78
diff --git a/tests/data/pep_570.py b/tests/data/pep_570.py
new file mode 100644
index 0000000..ca8f7ab
--- /dev/null
+++ b/tests/data/pep_570.py
@@ -0,0 +1,44 @@
+def positional_only_arg(a, /):
+    pass
+
+
+def all_markers(a, b, /, c, d, *, e, f):
+    pass
+
+
+def all_markers_with_args_and_kwargs(
+    a_long_one,
+    b_long_one,
+    /,
+    c_long_one,
+    d_long_one,
+    *args,
+    e_long_one,
+    f_long_one,
+    **kwargs,
+):
+    pass
+
+
+def all_markers_with_defaults(a, b=1, /, c=2, d=3, *, e=4, f=5):
+    pass
+
+
+def long_one_with_long_parameter_names(
+    but_all_of_them,
+    are_positional_only,
+    arguments_mmmmkay,
+    so_this_is_only_valid_after,
+    three_point_eight,
+    /,
+):
+    pass
+
+
+lambda a, /: a
+
+lambda a, b, /, c, d, *, e, f: a
+
+lambda a, b, /, c, d, *args, e, f, **kwargs: args
+
+lambda a, b=1, /, c=2, d=3, *, e=4, f=5: 1
diff --git a/tests/test_black.py b/tests/test_black.py
index be6d98a..4e0a03a 100644
--- a/tests/test_black.py
+++ b/tests/test_black.py
@@ -344,6 +344,23 @@ def test_fstring(self) -> None:
         black.assert_equivalent(source, actual)
         black.assert_stable(source, actual, black.FileMode())
 
+    @patch("black.dump_to_file", dump_to_stderr)
+    def test_pep_570(self) -> None:
+        source, expected = read_data("pep_570")
+        actual = fs(source)
+        self.assertFormatEqual(expected, actual)
+        black.assert_stable(source, actual, black.FileMode())
+        if sys.version_info >= (3, 8):
+            black.assert_equivalent(source, actual)
+
+    def test_detect_pos_only_arguments(self) -> None:
+        source, _ = read_data("pep_570")
+        root = black.lib2to3_parse(source)
+        features = black.get_features_used(root)
+        self.assertIn(black.Feature.POS_ONLY_ARGUMENTS, features)
+        versions = black.detect_target_versions(root)
+        self.assertIn(black.TargetVersion.PY38, versions)
+
     @patch("black.dump_to_file", dump_to_stderr)
     def test_string_quotes(self) -> None:
         source, expected = read_data("string_quotes")

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest pytest-cov pytest-xdist pytest-mock pytest-asyncio
3.9
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
appdirs==1.4.4
attrs==25.3.0
-e git+https://github.com/psf/black.git@d8fa8df0526de9c0968e0a3568008f58eae45364#egg=black
click==8.1.8
coverage==7.8.0
exceptiongroup==1.2.2
execnet==2.1.1
iniconfig==2.1.0
packaging==24.2
pluggy==1.5.0
pytest==8.3.5
pytest-asyncio==0.26.0
pytest-cov==6.0.0
pytest-mock==3.14.0
pytest-xdist==3.6.1
toml==0.10.2
tomli==2.2.1
typed-ast==1.5.5
typing_extensions==4.13.0

name: black
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - appdirs==1.4.4
      - attrs==25.3.0
      - black==19.3b0
      - click==8.1.8
      - coverage==7.8.0
      - exceptiongroup==1.2.2
      - execnet==2.1.1
      - iniconfig==2.1.0
      - packaging==24.2
      - pluggy==1.5.0
      - pytest==8.3.5
      - pytest-asyncio==0.26.0
      - pytest-cov==6.0.0
      - pytest-mock==3.14.0
      - pytest-xdist==3.6.1
      - toml==0.10.2
      - tomli==2.2.1
      - typed-ast==1.5.5
      - typing-extensions==4.13.0
prefix: /opt/conda/envs/black

tests/test_black.py::BlackTestCase::test_detect_pos_only_arguments tests/test_black.py::BlackTestCase::test_pep_570
tests/test_black.py::BlackTestCase::test_expression tests/test_black.py::BlackTestCase::test_expression_diff tests/test_black.py::BlackTestCase::test_expression_ff tests/test_black.py::BlackTestCase::test_shhh_click
tests/test_black.py::BlackTestCase::test_assertFormatEqual tests/test_black.py::BlackTestCase::test_assert_equivalent_different_asts tests/test_black.py::BlackTestCase::test_async_as_identifier tests/test_black.py::BlackTestCase::test_black tests/test_black.py::BlackTestCase::test_bracket_match tests/test_black.py::BlackTestCase::test_broken_symlink tests/test_black.py::BlackTestCase::test_cache_broken_file tests/test_black.py::BlackTestCase::test_cache_multiple_files tests/test_black.py::BlackTestCase::test_cache_single_file_already_cached tests/test_black.py::BlackTestCase::test_cantfit tests/test_black.py::BlackTestCase::test_check_diff_use_together tests/test_black.py::BlackTestCase::test_comment_after_escaped_newline tests/test_black.py::BlackTestCase::test_comments tests/test_black.py::BlackTestCase::test_comments2 tests/test_black.py::BlackTestCase::test_comments3 tests/test_black.py::BlackTestCase::test_comments4 tests/test_black.py::BlackTestCase::test_comments5 tests/test_black.py::BlackTestCase::test_comments6 tests/test_black.py::BlackTestCase::test_comments7 tests/test_black.py::BlackTestCase::test_composition tests/test_black.py::BlackTestCase::test_debug_visitor tests/test_black.py::BlackTestCase::test_empty tests/test_black.py::BlackTestCase::test_empty_exclude tests/test_black.py::BlackTestCase::test_empty_ff tests/test_black.py::BlackTestCase::test_empty_include tests/test_black.py::BlackTestCase::test_empty_lines tests/test_black.py::BlackTestCase::test_endmarker tests/test_black.py::BlackTestCase::test_failed_formatting_does_not_get_cached tests/test_black.py::BlackTestCase::test_filter_cached tests/test_black.py::BlackTestCase::test_fmtonoff tests/test_black.py::BlackTestCase::test_fmtonoff2 tests/test_black.py::BlackTestCase::test_format_file_contents tests/test_black.py::BlackTestCase::test_fstring tests/test_black.py::BlackTestCase::test_function tests/test_black.py::BlackTestCase::test_function2 tests/test_black.py::BlackTestCase::test_function_trailing_comma tests/test_black.py::BlackTestCase::test_get_features_used tests/test_black.py::BlackTestCase::test_get_future_imports tests/test_black.py::BlackTestCase::test_import_spacing tests/test_black.py::BlackTestCase::test_include_exclude tests/test_black.py::BlackTestCase::test_invalid_include_exclude tests/test_black.py::BlackTestCase::test_lib2to3_parse tests/test_black.py::BlackTestCase::test_multi_file_force_py36 tests/test_black.py::BlackTestCase::test_multi_file_force_pyi tests/test_black.py::BlackTestCase::test_new_line_between_class_and_code tests/test_black.py::BlackTestCase::test_no_cache_when_stdin tests/test_black.py::BlackTestCase::test_no_cache_when_writeback_diff tests/test_black.py::BlackTestCase::test_no_files tests/test_black.py::BlackTestCase::test_numeric_literals tests/test_black.py::BlackTestCase::test_numeric_literals_ignoring_underscores tests/test_black.py::BlackTestCase::test_numeric_literals_py2 tests/test_black.py::BlackTestCase::test_pep_572 tests/test_black.py::BlackTestCase::test_pep_572_version_detection tests/test_black.py::BlackTestCase::test_pipe_force_py36 tests/test_black.py::BlackTestCase::test_pipe_force_pyi tests/test_black.py::BlackTestCase::test_piping tests/test_black.py::BlackTestCase::test_piping_diff tests/test_black.py::BlackTestCase::test_preserves_line_endings tests/test_black.py::BlackTestCase::test_preserves_line_endings_via_stdin tests/test_black.py::BlackTestCase::test_python2 tests/test_black.py::BlackTestCase::test_python2_print_function tests/test_black.py::BlackTestCase::test_python2_unicode_literals tests/test_black.py::BlackTestCase::test_python37 tests/test_black.py::BlackTestCase::test_read_cache_line_lengths tests/test_black.py::BlackTestCase::test_read_cache_no_cachefile tests/test_black.py::BlackTestCase::test_remove_empty_parentheses_after_class tests/test_black.py::BlackTestCase::test_remove_parens tests/test_black.py::BlackTestCase::test_report_normal tests/test_black.py::BlackTestCase::test_report_quiet tests/test_black.py::BlackTestCase::test_report_verbose tests/test_black.py::BlackTestCase::test_root_logger_not_used_directly tests/test_black.py::BlackTestCase::test_self tests/test_black.py::BlackTestCase::test_setup tests/test_black.py::BlackTestCase::test_single_file_force_py36 tests/test_black.py::BlackTestCase::test_single_file_force_pyi tests/test_black.py::BlackTestCase::test_slices tests/test_black.py::BlackTestCase::test_string_prefixes tests/test_black.py::BlackTestCase::test_string_quotes tests/test_black.py::BlackTestCase::test_stub tests/test_black.py::BlackTestCase::test_symlink_out_of_root_directory tests/test_black.py::BlackTestCase::test_tab_comment_indentation tests/test_black.py::BlackTestCase::test_tuple_assign tests/test_black.py::BlackTestCase::test_write_cache_creates_directory_if_needed tests/test_black.py::BlackTestCase::test_write_cache_read_cache tests/test_black.py::BlackTestCase::test_write_cache_write_fail
black.py blib2to3/Grammar.txt
black.py blib2to3/Grammar.txt