I have a function that allows the user to perform sums, it can be called with up to 4 arguments depending on type, but for some reason it seems to be putting output on the screen I can't trace
The program is as follows
from typing import Union, Callable
def Sum(*args: Union[int, float, Callable[[Union[int, float]], Union[int, float]]]) -> Union[int, float]:
print("Sum called with args", args)
start, stop, step, func = __SumProdSetup("Sum", *args)
if len(args) == 4 and all([isinstance(arg, float) for arg in args[1:]]) and callable(args[0]):
#SUMMATION CODE
else:
print("Called", args, "space")
def __SumProdSetup(name: str, *args: Union[int, float, Callable[[Union[int, float]], Union[int, float]]]) -> tuple[Union[int, float], Union[int, float], Union[int, float], Callable[[Union[int, float]], Union[int, float]]]:
print("Setup called with args", args)
raiserr = False
# Add different args combinations
raiseerr=True #added here for testing purposes
if raiserr:
raise ValueError(f"""((ADD USAGES))""")
else:
try:
return start, stop, step, func
except NameError as err:
err.args = f"Usage: {', '.join([str(arg) for arg in args])}",
raise err
Sum()
As expected, this gives an ValueError, as no arguments is an invalid usage.
However, I'm also getting output that can't be traced. Nowhere in the code should it print 'Called'. It should (with a different usage) print 'Called' then the args, then 'space'. It should also never print 'None'
but yet, this is the full output: (Sum called and Setup called are expected)
Called
None
Sum called with args ()
Setup called with args ()
Traceback (most recent call last):
File "C:\Users\maxcu\OneDrive\JetbrainsProjects\python\Games\engine\__init__.py", line 173, in <module>
Sum()
File "C:\Users\maxcu\OneDrive\JetbrainsProjects\python\Games\engine\__init__.py", line 79, in Sum
start, stop, step, func = __SumProdSetup("Sum", *args)
File "C:\Users\maxcu\OneDrive\JetbrainsProjects\python\Games\engine\__init__.py", line 154, in __SumProdSetup
raise TypeError(f"""
TypeError:
Available usages:
Sum(int)
Sum(int, int)
Sum(float, float)
Sum(float, float, float)
Sum(Callable, int)
Sum(Callable, int, int)
Sum(Callable, float, float)
Sum(Callable, float, float, float)
The 'Called' and 'None' outputs are unexpected and using a search on the code yields only three results for print; none of these should output 'None' or 'Called' on its own
CodePudding user response:
Found the solution! One module I was importing was a custom module (not included in the snippet as it is only found on my machine and not used in the function causing the issue) and this had a line that printed the 'Called' and 'None' content
TL;DR A custom module was accidentally causing the problem
This question can be closed now
CodePudding user response:
While you might have found the culprit in your own instance, I was curious as to how this issue could be solved.
Here's one solution. Messing with builtins
in production or in any important context is almost always a bad idea, but for local debugging this might be useful:
import builtins
import inspect
setattr(builtins, "old_print", print)
def new_print(*args, **kwargs):
caller = inspect.stack()[1]
builtins.old_print(f"{caller.filename}:{caller.lineno} |", *args, **kwargs)
setattr(builtins, "print", new_print)
if __name__ == '__main__':
print("Hello world")
This takes print()
and appends the file and line number of the call to the output.
Result:
E:\DevProjects\stack-exchange-answers\69668677\trace_print_origin.py:15 | Hello world
Importing it into another file:
import trace_print_origin
print("Hello import")
Result running the second file:
E:\DevProjects\stack-exchange-answers\69668677\trace_print_origin_import.py:3 | Hello import