Reputation: 20618
I was playing with interactive shell, testing new stuff etc. I found a function has three flags.
def bar(x,y):
pass
>>> dis.show_code(bar)
Name: bar
Filename: test.py
Argument count: 2
Positional-only arguments: 0
Kw-only arguments: 0
Number of locals: 2
Stack size: 1
Flags: OPTIMIZED, NEWLOCALS, NOFREE
Constants:
0: None
Variable names:
0: x
1: y
Also a string has 1 flag
string = "s"
>>> dis.show_code(string)
Filename: <disassembly>
Flags: NOFREE
The question is why we have them or why do we need them?
Upvotes: 5
Views: 40749
Reputation: 15872
These FLAGS
signify different components of a code
object. While the other answer points you towards the right answer, I am just adding a little fun to the mix.
You can try importing a subset of FLAGS
from dis
.
>>> from dis import COMPILER_FLAG_NAMES
>>> COMPILER_FLAG_NAMES
{1: 'OPTIMIZED',
2: 'NEWLOCALS',
4: 'VARARGS',
8: 'VARKEYWORDS',
16: 'NESTED',
32: 'GENERATOR',
64: 'NOFREE',
128: 'COROUTINE',
256: 'ITERABLE_COROUTINE',
512: 'ASYNC_GENERATOR'}
And then you can write a simple function and see what FLAGS
show up:
>>> def foo():
return
>>> dis.show_code(foo)
Name: foo
Filename: <ipython-input-138-32384d979b8a>
Argument count: 0
Kw-only arguments: 0
Number of locals: 0
Stack size: 1
Flags: OPTIMIZED, NEWLOCALS, NOFREE
Constants:
0: None
Now, you can start increasing the complexity and see how that changes:
>>> def foo(a, *args, **kwargs):
yield a
>>> dis.show_code(foo)
Name: foo
Filename: <ipython-input-141-56a68ddd064c>
Argument count: 1
Kw-only arguments: 0
Number of locals: 3
Stack size: 1
Flags: OPTIMIZED, NEWLOCALS, VARARGS, VARKEYWORDS, GENERATOR, NOFREE
Constants:
0: None
Variable names:
0: a
1: args
2: kwargs
Here adding *args
, **kwargs
and yield
added VARARGS, VARKEYWORDS, GENERATOR
flags respectively.
Now for something a little more:
>>> from asyncio import coroutine
>>> @coroutine
async def foo(a, *args, **kwargs):
yield b
def bar():
return foo(b)
yield bar
>>> dis.show_code(foo)
Name: coro
Filename: C:\Users\sayan\Anaconda3\envs\tensorflow_gpu\lib\asyncio\coroutines.py
Argument count: 0
Kw-only arguments: 0
Number of locals: 4
Stack size: 8
Flags: OPTIMIZED, NEWLOCALS, VARARGS, VARKEYWORDS, NESTED, GENERATOR, ITERABLE_COROUTINE
Constants:
0: None
Names:
0: base_futures
1: isfuture
2: inspect
3: isgenerator
4: isinstance
5: CoroWrapper
6: __await__
7: AttributeError
8: collections
9: abc
10: Awaitable
Variable names:
0: args
1: kw
2: res
3: await_meth
Free variables:
0: func
And there you go, adding @coroutine
decorator gives NESTED
, async_def + yield
gives ITERABLE_COROUTINE
and the presence of a freevar, that is the function bar
here, removes the NOFREE
flag.
Upvotes: 3
Reputation: 19352
The documentation says:
The following flag bits are defined for co_flags: bit
0x04
is set if the function uses the*arguments
syntax to accept an arbitrary number of positional arguments; bit0x08
is set if the function uses the**keywords
syntax to accept arbitrary keyword arguments; bit0x20
is set if the function is a generator.Future feature declarations (
from __future__ import division
) also use bits inco_flags
to indicate whether a code object was compiled with a particular feature enabled: bit0x2000
is set if the function was compiled with future division enabled; bits0x10
and0x1000
were used in earlier versions of Python.Other bits in
co_flags
are reserved for internal use.
In the Python source code, you can find this more extensive list of flags in code.h
:
#define CO_OPTIMIZED 0x0001
#define CO_NEWLOCALS 0x0002
#define CO_VARARGS 0x0004
#define CO_VARKEYWORDS 0x0008
#define CO_NESTED 0x0010
#define CO_GENERATOR 0x0020
#define CO_NOFREE 0x0040
#define CO_COROUTINE 0x0080
#define CO_ITERABLE_COROUTINE 0x0100
#define CO_ASYNC_GENERATOR 0x0200
#define CO_FUTURE_DIVISION 0x20000
#define CO_FUTURE_ABSOLUTE_IMPORT 0x40000
#define CO_FUTURE_WITH_STATEMENT 0x80000
#define CO_FUTURE_PRINT_FUNCTION 0x100000
#define CO_FUTURE_UNICODE_LITERALS 0x200000
#define CO_FUTURE_BARRY_AS_BDFL 0x400000
#define CO_FUTURE_GENERATOR_STOP 0x800000
#define CO_FUTURE_ANNOTATIONS 0x1000000
Upvotes: 2