Skip to content

print / printed approach is too opinionated to be useful #290

@dnesting

Description

@dnesting

BUG/PROBLEM REPORT / FEATURE REQUEST

RestrictingNodeTransformer rewrites usage of print, and expects its output to be retrieved with printed. This is too opinionated for my use case (plus I have existing code that I want to use this on that uses a printed variable for its own purpose). I'd like to simply replace the print builtin with my own implementation that I can do whatever I want with, such as collect output in a file or a StringIO or similar where I can do something with it when execution completes.

Unfortunately it doesn't look like I can do that very easily, since the current print handling seems to be pervasive in the transformer's implementation. Overriding the methods in question seems to mean copy-pasting a lot of code.

I can't find any documentation that explains whether or not there's a good reason __builtins__.print just can't be overridden without all of the mangling that occurs in RestrictingNodeTransformer. Is there? Can you recommend a path forward for me?

What I expect to happen:

I'd love to be able to write a replacement print implementation that works something like:

stdout = StringIO()
stderr = StringIO()
glb = {
  'sys': {  # over-simplifying but you get the idea
    'stdout': stdout,
    'stderr': stderr,
  },
  '__builtins__': {}
}

def my_print(*args, sep=' ', end='\n', file=None, flush=False):
  if file is None:
    file = glb['sys']['stdout']
  print(*args, sep=sep, end=end, file=file, flush=flush)

glb['__builtins__']['print'] = my_print

exec(code, glb, {}, mode='exec')

print(stdout.getvalue())  # "...profit!"

What actually happened:

I am forced instead down a _print and PrintCollector journey that requires I modify the code I'm trying to execute by having it do something in the scope of the user code with printed. This seems like it requires a lot of code modification.

What version of Python and Zope/Addons I am using:

RestrictedPython==7.4
Cpython 3.12 on Darwin

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions