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