Last active
March 8, 2023 00:36
-
-
Save laundmo/6ac0e667d15657fdc61863d34e7d4877 to your computer and use it in GitHub Desktop.
Challenge where i tried to make something in python inaccessible, only edit the evaluate method. Rules at the bottom of the file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Private: | |
def __setattr__(self, name, value): | |
raise RuntimeError("Attribute setting disabled.") | |
def __call__(self, f): | |
super().__setattr__("f_code", f.__code__) | |
def wrapper(*args, **kwargs): | |
f.__code__ = self.f_code | |
if self.code == __import__("inspect").currentframe().f_back.f_code: | |
return f(*args, **kwargs) | |
raise RuntimeError("This private function cannot be called directly.") | |
return wrapper | |
def setcode(self, code): | |
super().__setattr__("code", code) | |
def alt(*args, **kwargs): | |
raise RuntimeError("Cannot set code state for this class, already set.") | |
super().__setattr__("setcode", alt) | |
def allowed(private): | |
def wrapper(f): | |
private.setcode(f.__code__) | |
return f | |
def alt(*args, **kwargs): | |
raise RuntimeError("Cannot set allowed state for other callers.") | |
allowed.__code__ = alt.__code__ | |
return wrapper | |
private = Private() | |
@private | |
def private_func(private=private): | |
print(id(private), id(private_func)) | |
return 1 | |
@allowed(private) | |
def permitted_caller(): | |
private_func() | |
print("called from the allowed caller") | |
del private | |
# After this line is only the code for evaluating | |
# you can completely ignore it | |
def evaluate(solution_code): | |
import io | |
from contextlib import redirect_stdout | |
sol = io.StringIO() | |
with redirect_stdout(sol): | |
exec( | |
solution_code, | |
globals().copy(), | |
) | |
match = io.StringIO() | |
with redirect_stdout(match): | |
permitted_caller() | |
usr_solution = sol.getvalue().split("\n")[:-1] | |
proper = match.getvalue().split("\n")[0] | |
print("Gotten:") | |
print(">>> " + "\n\t>".join(usr_solution)) | |
print("Expected:") | |
print(">>> " + proper) | |
if usr_solution == [proper]: | |
print("CONGRATULATIONS! you solved it!") | |
else: | |
print("Sorry, your solution printed more than private_func does") | |
# Challenge: call private_func() without calling permitted_caller() | |
# Rules: | |
# - Only modify the string which is passed to evaluate. | |
# - Your solution can't rely on opening this python file or a copy of it. | |
# - Don't re-create the function. | |
# - Don't interact with the evaluation code: its not part of the challenge. | |
# - Don't call permitted_caller at all. | |
# The evaluate tries to check, but it can't detect every rule-breaking solution. | |
evaluate( | |
""" | |
permitted_caller() | |
""" | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment