Skip to content

Commit ebea432

Browse files
Merge pull request #9672 from jakobandersen/py_nodes
Py, use more desc_sig_* nodes
2 parents 9922923 + 9c16825 commit ebea432

File tree

3 files changed

+184
-105
lines changed

3 files changed

+184
-105
lines changed

CHANGES

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ Incompatible changes
99

1010
* #9649: ``searchindex.js``: the embedded data has changed format to allow
1111
objects with the same name in different domains.
12+
* #9672: The rendering of Python domain declarations is implemented
13+
with more docutils nodes to allow better CSS styling.
14+
It may break existing styling.
15+
* #9672: the signature of
16+
:py:meth:`domains.py.PyObject.get_signature_prefix` has changed to
17+
return a list of nodes instead of a plain string.
1218

1319
Deprecated
1420
----------
@@ -22,6 +28,7 @@ Features added
2228
* #9691: C, added new info-field ``retval``
2329
for :rst:dir:`c:function` and :rst:dir:`c:macro`.
2430
* C++, added new info-field ``retval`` for :rst:dir:`cpp:function`.
31+
* #9672: More CSS classes on Python domain descriptions
2532

2633
Bugs fixed
2734
----------

sphinx/domains/python.py

Lines changed: 79 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,21 @@ def unparse(node: ast.AST) -> List[Node]:
118118
result.extend(unparse(node.right))
119119
return result
120120
elif isinstance(node, ast.BitOr):
121-
return [nodes.Text(' '), addnodes.desc_sig_punctuation('', '|'), nodes.Text(' ')]
121+
return [addnodes.desc_sig_space(),
122+
addnodes.desc_sig_punctuation('', '|'),
123+
addnodes.desc_sig_space()]
122124
elif isinstance(node, ast.Constant): # type: ignore
123125
if node.value is Ellipsis:
124126
return [addnodes.desc_sig_punctuation('', "...")]
127+
elif isinstance(node.value, bool):
128+
return [addnodes.desc_sig_keyword('', repr(node.value))]
129+
elif isinstance(node.value, int):
130+
return [addnodes.desc_sig_literal_number('', repr(node.value))]
131+
elif isinstance(node.value, str):
132+
return [addnodes.desc_sig_literal_string('', repr(node.value))]
125133
else:
134+
# handles None, which is further handled by type_to_xref later
135+
# and fallback for other types that should be converted
126136
return [nodes.Text(repr(node.value))]
127137
elif isinstance(node, ast.Expr):
128138
return unparse(node.value)
@@ -136,7 +146,9 @@ def unparse(node: ast.AST) -> List[Node]:
136146
# once
137147
for elem in node.elts:
138148
result.extend(unparse(elem))
139-
result.append(addnodes.desc_sig_punctuation('', ', '))
149+
result.append(addnodes.desc_sig_punctuation('', ','))
150+
result.append(addnodes.desc_sig_space())
151+
result.pop()
140152
result.pop()
141153
result.append(addnodes.desc_sig_punctuation('', ']'))
142154
return result
@@ -161,7 +173,9 @@ def unparse(node: ast.AST) -> List[Node]:
161173
result = []
162174
for elem in node.elts:
163175
result.extend(unparse(elem))
164-
result.append(addnodes.desc_sig_punctuation('', ', '))
176+
result.append(addnodes.desc_sig_punctuation('', ','))
177+
result.append(addnodes.desc_sig_space())
178+
result.pop()
165179
result.pop()
166180
else:
167181
result = [addnodes.desc_sig_punctuation('', '('),
@@ -222,13 +236,13 @@ def _parse_arglist(arglist: str, env: BuildEnvironment = None) -> addnodes.desc_
222236
if param.annotation is not param.empty:
223237
children = _parse_annotation(param.annotation, env)
224238
node += addnodes.desc_sig_punctuation('', ':')
225-
node += nodes.Text(' ')
239+
node += addnodes.desc_sig_space()
226240
node += addnodes.desc_sig_name('', '', *children) # type: ignore
227241
if param.default is not param.empty:
228242
if param.annotation is not param.empty:
229-
node += nodes.Text(' ')
243+
node += addnodes.desc_sig_space()
230244
node += addnodes.desc_sig_operator('', '=')
231-
node += nodes.Text(' ')
245+
node += addnodes.desc_sig_space()
232246
else:
233247
node += addnodes.desc_sig_operator('', '=')
234248
node += nodes.inline('', param.default, classes=['default_value'],
@@ -418,11 +432,11 @@ class PyObject(ObjectDescription[Tuple[str, str]]):
418432

419433
allow_nesting = False
420434

421-
def get_signature_prefix(self, sig: str) -> str:
435+
def get_signature_prefix(self, sig: str) -> List[nodes.Node]:
422436
"""May return a prefix to put before the object name in the
423437
signature.
424438
"""
425-
return ''
439+
return []
426440

427441
def needs_arglist(self) -> bool:
428442
"""May return true if an empty argument list is to be generated even if
@@ -476,7 +490,7 @@ def handle_signature(self, sig: str, signode: desc_signature) -> Tuple[str, str]
476490

477491
sig_prefix = self.get_signature_prefix(sig)
478492
if sig_prefix:
479-
signode += addnodes.desc_annotation(sig_prefix, sig_prefix)
493+
signode += addnodes.desc_annotation(str(sig_prefix), '', *sig_prefix)
480494

481495
if prefix:
482496
signode += addnodes.desc_addname(prefix, prefix)
@@ -507,7 +521,9 @@ def handle_signature(self, sig: str, signode: desc_signature) -> Tuple[str, str]
507521

508522
anno = self.options.get('annotation')
509523
if anno:
510-
signode += addnodes.desc_annotation(' ' + anno, ' ' + anno)
524+
signode += addnodes.desc_annotation(' ' + anno, '',
525+
addnodes.desc_sig_space(),
526+
nodes.Text(anno))
511527

512528
return fullname, prefix
513529

@@ -609,11 +625,12 @@ class PyFunction(PyObject):
609625
'async': directives.flag,
610626
})
611627

612-
def get_signature_prefix(self, sig: str) -> str:
628+
def get_signature_prefix(self, sig: str) -> List[nodes.Node]:
613629
if 'async' in self.options:
614-
return 'async '
630+
return [addnodes.desc_sig_keyword('', 'async'),
631+
addnodes.desc_sig_space()]
615632
else:
616-
return ''
633+
return []
617634

618635
def needs_arglist(self) -> bool:
619636
return True
@@ -670,11 +687,17 @@ def handle_signature(self, sig: str, signode: desc_signature) -> Tuple[str, str]
670687
typ = self.options.get('type')
671688
if typ:
672689
annotations = _parse_annotation(typ, self.env)
673-
signode += addnodes.desc_annotation(typ, '', nodes.Text(': '), *annotations)
690+
signode += addnodes.desc_annotation(typ, '',
691+
addnodes.desc_sig_punctuation('', ':'),
692+
addnodes.desc_sig_space(), *annotations)
674693

675694
value = self.options.get('value')
676695
if value:
677-
signode += addnodes.desc_annotation(value, ' = ' + value)
696+
signode += addnodes.desc_annotation(value, '',
697+
addnodes.desc_sig_space(),
698+
addnodes.desc_sig_punctuation('', '='),
699+
addnodes.desc_sig_space(),
700+
nodes.Text(value))
678701

679702
return fullname, prefix
680703

@@ -698,11 +721,12 @@ class PyClasslike(PyObject):
698721

699722
allow_nesting = True
700723

701-
def get_signature_prefix(self, sig: str) -> str:
724+
def get_signature_prefix(self, sig: str) -> List[nodes.Node]:
702725
if 'final' in self.options:
703-
return 'final %s ' % self.objtype
726+
return [nodes.Text('final'), addnodes.desc_sig_space(),
727+
nodes.Text(self.objtype), addnodes.desc_sig_space()]
704728
else:
705-
return '%s ' % self.objtype
729+
return [nodes.Text(self.objtype), addnodes.desc_sig_space()]
706730

707731
def get_index_text(self, modname: str, name_cls: Tuple[str, str]) -> str:
708732
if self.objtype == 'class':
@@ -734,25 +758,27 @@ def needs_arglist(self) -> bool:
734758
else:
735759
return True
736760

737-
def get_signature_prefix(self, sig: str) -> str:
738-
prefix = []
761+
def get_signature_prefix(self, sig: str) -> List[nodes.Node]:
762+
prefix: List[nodes.Node] = []
739763
if 'final' in self.options:
740-
prefix.append('final')
764+
prefix.append(nodes.Text('final'))
765+
prefix.append(addnodes.desc_sig_space())
741766
if 'abstractmethod' in self.options:
742-
prefix.append('abstract')
767+
prefix.append(nodes.Text('abstract'))
768+
prefix.append(addnodes.desc_sig_space())
743769
if 'async' in self.options:
744-
prefix.append('async')
770+
prefix.append(nodes.Text('async'))
771+
prefix.append(addnodes.desc_sig_space())
745772
if 'classmethod' in self.options:
746-
prefix.append('classmethod')
773+
prefix.append(nodes.Text('classmethod'))
774+
prefix.append(addnodes.desc_sig_space())
747775
if 'property' in self.options:
748-
prefix.append('property')
776+
prefix.append(nodes.Text('property'))
777+
prefix.append(addnodes.desc_sig_space())
749778
if 'staticmethod' in self.options:
750-
prefix.append('static')
751-
752-
if prefix:
753-
return ' '.join(prefix) + ' '
754-
else:
755-
return ''
779+
prefix.append(nodes.Text('static'))
780+
prefix.append(addnodes.desc_sig_space())
781+
return prefix
756782

757783
def get_index_text(self, modname: str, name_cls: Tuple[str, str]) -> str:
758784
name, cls = name_cls
@@ -831,11 +857,18 @@ def handle_signature(self, sig: str, signode: desc_signature) -> Tuple[str, str]
831857
typ = self.options.get('type')
832858
if typ:
833859
annotations = _parse_annotation(typ, self.env)
834-
signode += addnodes.desc_annotation(typ, '', nodes.Text(': '), *annotations)
860+
signode += addnodes.desc_annotation(typ, '',
861+
addnodes.desc_sig_punctuation('', ':'),
862+
addnodes.desc_sig_space(),
863+
*annotations)
835864

836865
value = self.options.get('value')
837866
if value:
838-
signode += addnodes.desc_annotation(value, ' = ' + value)
867+
signode += addnodes.desc_annotation(value, '',
868+
addnodes.desc_sig_space(),
869+
addnodes.desc_sig_punctuation('', '='),
870+
addnodes.desc_sig_space(),
871+
nodes.Text(value))
839872

840873
return fullname, prefix
841874

@@ -870,19 +903,25 @@ def handle_signature(self, sig: str, signode: desc_signature) -> Tuple[str, str]
870903
typ = self.options.get('type')
871904
if typ:
872905
annotations = _parse_annotation(typ, self.env)
873-
signode += addnodes.desc_annotation(typ, '', nodes.Text(': '), *annotations)
906+
signode += addnodes.desc_annotation(typ, '',
907+
addnodes.desc_sig_punctuation('', ':'),
908+
addnodes.desc_sig_space(),
909+
*annotations)
874910

875911
return fullname, prefix
876912

877-
def get_signature_prefix(self, sig: str) -> str:
878-
prefix = []
913+
def get_signature_prefix(self, sig: str) -> List[nodes.Node]:
914+
prefix: List[nodes.Node] = []
879915
if 'abstractmethod' in self.options:
880-
prefix.append('abstract')
916+
prefix.append(nodes.Text('abstract'))
917+
prefix.append(addnodes.desc_sig_space())
881918
if 'classmethod' in self.options:
882-
prefix.append('class')
919+
prefix.append(nodes.Text('class'))
920+
prefix.append(addnodes.desc_sig_space())
883921

884-
prefix.append('property')
885-
return ' '.join(prefix) + ' '
922+
prefix.append(nodes.Text('property'))
923+
prefix.append(addnodes.desc_sig_space())
924+
return prefix
886925

887926
def get_index_text(self, modname: str, name_cls: Tuple[str, str]) -> str:
888927
name, cls = name_cls

0 commit comments

Comments
 (0)