Created
July 6, 2023 14:33
-
-
Save strictlymike/b985b774d7b731bd0fecaecb239d674a to your computer and use it in GitHub Desktop.
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
# Copyright 2023 Google LLC. | |
# SPDX-License-Identifier: Apache-2.0 | |
# This snippet of Py3 code shows a way to pass a restricted object to a callee, | |
# so as to prevent the callee from wandering outside the walled garden of callbacks | |
# specified by a given mixin. It does not secure the original instance from tampering, | |
# but it removes all doubt about which methods are expected to be accessed and used | |
# by the callee. | |
# | |
# This assumes the lifetime of the original instance will exceed that of the | |
# restricted object. There may be other assumptions inherent here, as well. | |
# Use at your own risk. Constructive feedback welcome. | |
import inspect | |
def create_restricted_binding(instance, mixin): | |
class RestrictedBinding(object): | |
pass | |
o = RestrictedBinding() | |
for name, function in inspect.getmembers(mixin, predicate=inspect.isfunction): | |
bound_method = getattr(instance, name) | |
setattr(o, name, bound_method) | |
return o | |
class PeasantMixin(): | |
def peasantMethod(self): return 0 | |
class Snooty(PeasantMixin): | |
def __init__(self, x): self._x = x | |
def snootyMethod(self): return self._x | |
snoot = Snooty(3) | |
peasant = create_restricted_binding(snoot, PeasantMixin) | |
print(peasant.peasantMethod()) // Prints "0" | |
print(peasant.snootyMethod()) // Raises AttributeError, as desired |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment