forked from universal-ctags/ctags
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ctags-lang-python.7.rst.in
286 lines (215 loc) · 11.4 KB
/
ctags-lang-python.7.rst.in
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
.. _ctags-lang-python(7):
==============================================================
ctags-lang-python
==============================================================
-------------------------------------------------------------------
Random notes about tagging python source code with Universal Ctags
-------------------------------------------------------------------
:Version: @VERSION@
:Manual group: Universal Ctags
:Manual section: 7
SYNOPSIS
--------
| **@CTAGS_NAME_EXECUTABLE@** ... --languages=+Python ...
| **@CTAGS_NAME_EXECUTABLE@** ... --language-force=Python ...
| **@CTAGS_NAME_EXECUTABLE@** ... --map-Python=+.py ...
DESCRIPTION
-----------
This man page gathers random notes about tagging python source code.
TAGGING ``import`` STATEMENTS
-----------------------------
Summary
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
`import X`
==== ========== ================== ===================
name kind role other noticeable fields
==== ========== ================== ===================
X module imported N/A
==== ========== ================== ===================
`import X as Y`
==== ========== ================== ===================
name kind role other noticeable fields
==== ========== ================== ===================
X module indirectlyImported N/A
Y namespace definition nameref:module:X
==== ========== ================== ===================
`from X import *`
==== ========== ================== ===================
name kind role other noticeable fields
==== ========== ================== ===================
`X` module namespace N/A
==== ========== ================== ===================
`from X import Y`
==== ========== ================== ===================
name kind role other noticeable fields
==== ========== ================== ===================
`X` module namespace N/A
`Y` unknown imported scope:module:`X`
==== ========== ================== ===================
`from X import Y as Z`
==== ========== ================== ===================
name kind role other noticeable fields
==== ========== ================== ===================
`X` module namespace N/A
`Y` unknown indirectlyImported scope:module:`X`
`Z` unknown definition nameref:unknown:`X`
==== ========== ================== ===================
..
===================== ==== ========== ================== ===================
input code name kind role other noticeable fields
===================== ==== ========== ================== ===================
import X X module imported
import X as Y X module indirectlyImported
import X as Y Y namespace definition nameref:module:X
from X import * X module namespace
from X import Y X module namespace
from X import Y Y unknown imported scope:module:X
from X import Y as Z X module namespace
from X import Y as Z Y unknown indirectlyImported scope:module:X
from X import Y as Z Z unknown definition nameref:unknown:X
===================== ==== ========== ================== ===================
.. a table having merged cells cannot be converted to man page
..
+--------------------+------------------------------------------------------+
|input code |output tags |
| +----+----------+------------------+-------------------+
| |name| kind |role |other noticeable fields |
+====================+====+==========+==================+===================+
|import X |X | module |imported | |
+--------------------+----+----------+------------------+-------------------+
|import X as Y |X | module |indirectlyImported| |
| +----+----------+------------------+-------------------+
| |Y | namespace|definition |nameref:module:X |
+--------------------+----+----------+------------------+-------------------+
|from X import * |X | module |namespace | |
+--------------------+----+----------+------------------+-------------------+
|from X import Y |X | module |namespace | |
| +----+----------+------------------+-------------------+
| |Y | unknown |imported |scope:module:X |
+--------------------+----+----------+------------------+-------------------+
|from X import Y as Z|X | module |namespace | |
| +----+----------+------------------+-------------------+
| |Y | unknown |indirectlyImported|scope:module:X |
| +----+----------+------------------+-------------------+
| |Z | unknown |definition |nameref:unknown:Y |
+--------------------+----+----------+------------------+-------------------+
Examples
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"input.py"
.. code-block:: Python
import X0
"output.tags"
with "--options=NONE -o - --extras=+r --fields=+rzK input.py"
.. code-block:: tags
X0 input.py /^import X0$/;" kind:module roles:imported
A tag for an imported module has ``module`` kind with ``imported`` role. The
module is not defined here; it is defined in another file. So the tag for the
imported module is a reference tag; specify ``--extras=+r`` (or
``--extras=+{reference}``) option for tagging it. "roles:" field enabled with
``--fields=+r`` is for recording the module is "imported" to the tag file.
"input.py"
.. code-block:: Python
import X1 as Y1
"output.tags"
with "--options=NONE -o - --extras=+r --fields=+rzK --fields-Python=+{nameref} input.py"
.. code-block:: tags
X1 input.py /^import X1 as Y1$/;" kind:module roles:indirectlyImported
Y1 input.py /^import X1 as Y1$/;" kind:namespace roles:def nameref:module:X1
"Y1" introduces a new name and is defined here. So "Y1" is tagged as a
definition tag. "X1" is imported in a way that its name cannot be used
in this source file. For letting client tools know that the name cannot be used,
``indirectlyImported`` role is assigned for "X1". "Y1" is the name for
accessing objects defined in the module imported via "X1". For recording this
relationship, ``nameref:`` field is attached to the tag of "Y1". Instead of
``module`` kind, ``namespace`` kind is assigned to "Y1" because "Y1" itself
isn't a module.
"input.py"
.. code-block:: Python
from X2 import *
"output.tags"
with "--options=NONE -o - --extras=+r --fields=+rzK input.py"
.. code-block:: tags
X2 input.py /^from X2 import *$/;" kind:module roles:namespace
The module is not defined here; it is defined in another file. So the tag for
the imported module is a reference tag. Unlike "X0" in "import X0", "X2" may not
be used because the names defined in "X2" can be used in this source file. To represent
the difference ``namespace`` role is attached to "X2" instead of ``imported``.
"input.py"
.. code-block:: Python
from X3 import Y3
"output.tags"
with "--options=NONE -o - --extras=+r --fields=+rzKZ input.py"
.. code-block:: tags
X3 input.py /^from X3 import Y3$/;" kind:module roles:namespace
Y3 input.py /^from X3 import Y3$/;" kind:unknown scope:module:X3 roles:imported
"Y3" is a name for a language object defined in "X3" module. "scope:module:X3"
attached to "Y3" represents this relation between "Y3" and "X3". ctags
assigns ``unknown`` kind to "Y3" because ctags cannot know whether "Y3" is a
class, a variable, or a function from the input file.
"input.py"
.. code-block:: Python
from X4 import Y4 as Z4
"output.tags"
with "--options=NONE -o - --extras=+r --fields=+rzKZ input.py"
.. code-block:: tags
X4 input.py /^from X4 import Y4 as Z4$/;" kind:module roles:namespace
Y4 input.py /^from X4 import Y4 as Z4$/;" kind:unknown scope:module:X4 roles:indirectlyImported
Z4 input.py /^from X4 import Y4 as Z4$/;" kind:unknown roles:def nameref:unknown:Y4
"Y4" is similar to "Y3" of "from X3 import Y3" but the name cannot be used here.
``indirectlyImported`` role assigned to "Y4" representing this. "Z4" is the name for
accessing the language object named in "Y4" in "X4" module. "nameref:unknown:Y4"
attached to "Z4" and "scope:module:X4" attached to "Y4" represent the relations.
LAMBDA EXPRESSION AND TYPE HINT
-------------------------------
Summary
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
`id = lambda var0: var0`
=========== ========== ================== ===================
name kind role other noticeable fields
=========== ========== ================== ===================
`id` function definition signature:(`var0`)
=========== ========== ================== ===================
`id_t: Callable[[int], int] = lambda var1: var1`
=========== ========== ================== ===================
name kind role other noticeable fields
=========== ========== ================== ===================
`id_t` variable definition typeref:typename:`Callable[[int], int]` nameref:function:anonFuncN
anonFuncN function definition signature:(`var1`)
=========== ========== ================== ===================
Examples
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"input.py"
.. code-block:: Python
from typing import Callable
id = lambda var0: var0
id_t: Callable[[int], int] = lambda var1: var1
"output.tags"
with "--options=NONE -o - --sort=no --fields=+KS --fields-Python=+{nameref} --extras=+{anonymous} input.py"
.. code-block:: tags
id input.py /^id = lambda var0: var0$/;" function signature:(var0)
id_t input.py /^id_t: Callable[[int], int] = lambda var1: var1$/;"\
variable typeref:typename:Callable[[int], int] nameref:function:anonFunc84011d2c0101
anonFunc84011d2c0101 input.py /^id_t: Callable[[int], int] = lambda var1: var1$/;"\
function signature:(var1)
If a variable ("id") with no type hint is initialized with a lambda expression,
ctags assigns ``function`` kind for the tag of "id".
If a variable ("id_t") with a type hint is initialized with a lambda expression,
ctags assigns ``variable`` kind for the tag of "id_t" with ``typeref:`` and
``nameref:`` fields. ctags fills ``typeref:`` field with the value of the type
hint. The way of filling ``nameref:`` is a bit complicated.
For the lambda expression used in initializing the type-hint'ed variable, ctags
creates ``anonymous`` extra tag ("anonFunc84011d2c0101"). ctags fills the
``nameref:`` field of "id_t" with the name of ``anonymous`` extra tag:
"nameref:function:anonFunc84011d2c0101".
You may think why ctags does so complicated, and why ctags doesn't emit
following tags output for the input::
id input.py /^id = \\$/;" function signature:(var0)
id_t input.py /^id_t: \\$/;" function typeref:typename:Callable[[int], int] signature:(var1)
There is a reason. The other languages of ctags obey the following rule: ctags fills
``typeref:`` field for a tag of a callable object (like function) with the type
of its return value. If we consider "id_t" is a function, its ``typeref:`` field
should have "typename:int". However, for filling ``typeref:`` with "typename:int",
ctags has to analyze "Callable[[int], int]" deeper. We don't want to do so.
SEE ALSO
--------
ctags(1), ctags-client-tools(7), ctags-lang-iPythonCell(7)