Python Forum
problem in output of a function
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
problem in output of a function
#1
hi
the below code is in https://realpython.com/python-eval-function/ :
def eval_expression(input_string):
    # Step 1
    allowed_names = {"sum": sum}
    # Step 2
    code = compile(input_string, "<string>", "eval")
    # Step 3
    for name in code.co_names:
        if name not in allowed_names:
            # Step 4
            raise NameError(f"Use of {name} not allowed")
    return eval(code, {"__builtins__": {}}, allowed_names)

eval_expression("pow(10, 2)")
when I run it in idle, my output is :
Error:
Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 10, in eval_expression NameError: Use of pow not allowed raise NameError(f"Use of {name} not allowed") NameError: Use of pow not allowed
in above output, in the 5'th line the{name} must be the pow as it is in the output of the site.
what is the problem?
thanks
Reply
#2
If you want to evaluate an expression that contains "pow", you need to add "pow" to allowed_names.
Reply
#3
(Sep-27-2023, 12:47 PM)deanhystad Wrote: If you want to evaluate an expression that contains "pow", you need to add "pow" to allowed_names.

in error message, in the line before last line, {name} must be pow, but as you can see it is {name}. why?
Reply
#4
This is the python expression that raises the exception.
raise NameError(f"Use of {name} not allowed")
It is line 10 in your posted code.
The expression on line 10 raises an exception with this message:
Error:
NameError: Use of pow not allowed
The f"string replaces {name} with "pow", the str referenced by name. This changes the str passed to the exception. It does not rewrite the code on line 10.

Another example might help. I run this code:
x = list("ABC")
for i in range(4):
    print(x[i])
I get an index error.
Error:
A B C Traceback (most recent call last): File "...", line 3, in <module> print(x[i]) IndexError: list index out of range
The line before the "IndexError" message is the statement that raised the exception. It says "print(x[i])". It does not say "print(x[3])". Granted, it would be very cool if error reporting replaced variables with their current values at the time of the error, but that is not what Python does. It might not even be possible. Accessing the variable value may be the reason for the exception.
akbarza likes this post
Reply
#5
(Sep-27-2023, 08:14 PM)deanhystad Wrote: This is the python expression that raises the exception.
raise NameError(f"Use of {name} not allowed")
It is line 10 in your posted code.
The expression on line 10 raises an exception with this message:
Error:
NameError: Use of pow not allowed
The f"string replaces {name} with "pow", the str referenced by name. This changes the str passed to the exception. It does not rewrite the code on line 10. Understand?
yes, i understand
Reply
#6
You are too quick. Or I am too slow. I really like the second example I thought of after my initial reply. Much better than "Understand?"
Reply
#7
(Sep-27-2023, 08:30 PM)deanhystad Wrote: You are too quick. Or I am too slow. I really like the second example I thought of after my initial reply. Much better than "Understand?"

hi, and thanks for the reply
can I ask about
code.co_names
? what does co_names do? where can I get more info about it?
On the whole, when I encounter a new word or thing in a code, how can I get info about it(other than googling)?
thanks again
Reply
#8
(Sep-28-2023, 06:59 AM)akbarza Wrote: ? what does co_names do? where can I get more info about it?
It's an attribute(method) of built-in compile().
So if want look more at it has to look tutorials about compile(),
and not .co_names alone which is just one method.
>>> code = compile('print(55)', 'test', 'eval')
>>> exec(code)
55

# Use a couple of methods 
>>> code.co_names
('print',)
>>> code.co_code
b'\x97\x00\x02\x00e\x00d\x00\xa6\x01\x00\x00\xab\x01\x00\x00\x00\x00\x00\x00\x00\x00S\x00'

# All 
>>> [i for i in dir(code) if not i.startswith('__')]
['_co_code_adaptive', '_varname_from_oparg', 'co_argcount', 'co_cellvars', 'co_code',
'co_consts', 'co_exceptiontable', 'co_filename', 'co_firstlineno', 'co_flags', 'co_freevars',
'co_kwonlyargcount', 'co_lines', 'co_linetable', 'co_lnotab', 'co_name', 'co_names', 'co_nlocals',
'co_positions', 'co_posonlyargcount', 'co_qualname', 'co_stacksize', 'co_varnames', 'replace']

# look at help for compile
>>> help(compile)
Help on built-in function compile in module builtins:

compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1, *, _feature_version=-1)
    Compile source into a code object that can be executed by exec() or eval().

    The source code may represent a Python module, statement or expression.
    The filename will be used for run-time error messages.
    The mode must be 'exec' to compile a module, 'single' to compile a
    single (interactive) statement, or 'eval' to compile an expression.
    The flags argument, if present, controls which future statements influence
    the compilation of the code.
    The dont_inherit argument, if true, stops the compilation inheriting
    the effects of any future statements in effect in the code calling
    compile; if absent or false these statements do influence the compilation,
    in addition to any features explicitly specified.
akbarza likes this post
Reply
#9
(Sep-28-2023, 03:26 PM)snippsat Wrote:
(Sep-28-2023, 06:59 AM)akbarza Wrote: ? what does co_names do? where can I get more info about it?
It's an attribute(method) of built-in compile().
So if want look more at it has to look tutorials about compile(),
and not .co_names alone which is just one method.
>>> code = compile('print(55)', 'test', 'eval')
>>> exec(code)
55

# Use a couple of methods 
>>> code.co_names
('print',)
>>> code.co_code
b'\x97\x00\x02\x00e\x00d\x00\xa6\x01\x00\x00\xab\x01\x00\x00\x00\x00\x00\x00\x00\x00S\x00'

# All 
>>> [i for i in dir(code) if not i.startswith('__')]
['_co_code_adaptive', '_varname_from_oparg', 'co_argcount', 'co_cellvars', 'co_code',
'co_consts', 'co_exceptiontable', 'co_filename', 'co_firstlineno', 'co_flags', 'co_freevars',
'co_kwonlyargcount', 'co_lines', 'co_linetable', 'co_lnotab', 'co_name', 'co_names', 'co_nlocals',
'co_positions', 'co_posonlyargcount', 'co_qualname', 'co_stacksize', 'co_varnames', 'replace']

# look at help for compile
>>> help(compile)
Help on built-in function compile in module builtins:

compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1, *, _feature_version=-1)
    Compile source into a code object that can be executed by exec() or eval().

    The source code may represent a Python module, statement or expression.
    The filename will be used for run-time error messages.
    The mode must be 'exec' to compile a module, 'single' to compile a
    single (interactive) statement, or 'eval' to compile an expression.
    The flags argument, if present, controls which future statements influence
    the compilation of the code.
    The dont_inherit argument, if true, stops the compilation inheriting
    the effects of any future statements in effect in the code calling
    compile; if absent or false these statements do influence the compilation,
    in addition to any features explicitly specified.

hi and thanks for replying
if I want to know about co_code or co_names, how can I do it?
i wrote
help(compile.co_code)
and
compile.co_names.__doc__ 
, but i get error.
Reply
#10
(Sep-29-2023, 07:31 AM)akbarza Wrote: if I want to know about co_code or co_names, how can I do it?
They are method of complie(),so you most use compile first.
>>> code = compile('print(55)', 'test', 'eval')
>>> help(code.co_names)
Help on tuple object:

class tuple(object)
 |  tuple(iterable=(), /)
.....
There is no doc string so help will only return help on tuple return.
To see some help on this can look at Code objects,so this a more special case than most other stuff.
If eg use Rich can see all methods at once.
>>>from rich import inspect

>>> code = compile('print(55)', 'test', 'eval')
>>> inspect(code)
┌────────────────────────────── <class 'code'> ───────────────────────────────┐
│ Create a code object.  Not for the faint of heart.                          │
│                                                                             │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ <code object <module> at 0x0000015DAB3A86B0, file "test", line 1>       │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
│                                                                             │
│        co_argcount = 0                                                      │
│        co_cellvars = ()                                                     │
│            co_code = b'\x97\x00\x02\x00e\x00d\x00\xa6\x01\x00\x00\xab\x01\… │
│          co_consts = (55,)                                                  │
│  co_exceptiontable = b''                                                    │
│        co_filename = 'test'                                                 │
│     co_firstlineno = 1                                                      │
│           co_flags = 0                                                      │
│        co_freevars = ()                                                     │
│  co_kwonlyargcount = 0                                                      │
│       co_linetable = b'\xf0\x03\x01\x01\x01\xd8\x00\x05\x80\x05\x80b\x81\t… │
│          co_lnotab = b'\x00\xff\x02\x01'                                    │
│            co_name = '<module>'                                             │
│           co_names = ('print',)                                             │
│         co_nlocals = 0                                                      │
│ co_posonlyargcount = 0                                                      │
│        co_qualname = '<module>'                                             │
│       co_stacksize = 3                                                      │
│        co_varnames = ()                                                     │
└─────────────────────────────────────────────────────────────────────────────┘

Here how it look if use eg make string hello,then will see that it has doc string for all string methods.
[Image: MAjEfa.png]
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  problem in output of a snippet code akbarza 2 387 Feb-28-2024, 07:15 PM
Last Post: deanhystad
  output shape problem with np.arange alan6690 5 702 Dec-26-2023, 05:44 PM
Last Post: deanhystad
  Python Pandas Syntax problem? Wrong Output, any ideas? Gbuoy 2 937 Jan-18-2023, 10:02 PM
Last Post: snippsat
  Facing problem with Pycharm - Not getting the expected output amortal03 1 865 Sep-09-2022, 05:44 PM
Last Post: Yoriz
  How to print the output of a defined function bshoushtarian 4 1,320 Sep-08-2022, 01:44 PM
Last Post: deanhystad
  output correction using print() function afefDXCTN 3 11,110 Sep-18-2021, 06:57 PM
Last Post: Sky_Mx
  python prints none in function output chairmanme0wme0w 3 2,232 Jul-07-2021, 05:18 PM
Last Post: deanhystad
  print function output wrong with strings. mposwal 5 3,137 Feb-12-2021, 09:04 AM
Last Post: DPaul
  Output with none, print(x) in function Vidar567 3 2,524 Nov-24-2020, 05:40 PM
Last Post: deanhystad
  single input infinite output problem Chase91 2 1,957 Sep-23-2020, 10:01 PM
Last Post: Chase91

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020