Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 1082941
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 16, 20262026-05-16T22:22:07+00:00 2026-05-16T22:22:07+00:00

Given an object A, which contains a callable object B, is there a way

  • 0

Given an object A, which contains a callable object B, is there a way to determine “A” from inside B.__call__()?

This is for use in test injection, where A.B is originally a method.

The code is something like this:

# Class to be tested.
class Outer(object):
  def __init__(self, arg):
    self.arg = arg
  def func(self, *args, **kwargs):
    print ('Outer self: %r' % (self,))

# Framework-provided:
class Injected(object):
  def __init__(self):
    self._replay = False
    self._calls = []
  def replay(self):
    self._replay = True
    self._calls.reverse()
  def __call__(self, *args, **kwargs):
    if not self._replay:
      expected = (args[0], args[1:], kwargs)
      self._calls.append(expected)
    else:
      expected_s, expected_a, expected_k = self._calls.pop()
      ok = True
      # verify args, similar for expected_k == kwargs
      ok = reduce(lambda x, comp: x and comp[0](comp[1]),
                  zip(expected_a, args),
                  ok)
      # what to do for expected_s == self?
      # ok = ok and expected_s(this) ### <= need "this". ###
      if not ok:
        raise Exception('Expectations not matched.')

# Inject:
setattr(Outer, 'func', Injected())
# Set expectations:
# - One object, initialised with "3", must pass "here" as 2nd arg.
# - One object, initialised with "4", must pass "whatever" as 1st arg.
Outer.func(lambda x: x.arg == 3, lambda x: True, lambda x: x=='here')
Outer.func(lambda x: x.arg == 4, lambda x: x=='whatever', lambda x: True)
Outer.func.replay()
# Invoke other code, which ends up doing:
o = Outer(3)
p = Outer(5)
o.func('something', 'here')
p.func('whatever', 'next')  # <- This should fail, 5 != 4

The question is: Is there a way (black magic is fine) within Injected.__call__() to access what “self” would have been in non-overwritten Outer.func(), to use as “this” (line marked with “###”)?

Naturally, the code is a bit more complex (the calls can be configured to be in arbitrary order, return values can be set, etc.), but this is the minimal example I could come up with that demonstrates both the problem and most of the constraints.

I cannot inject a function with a default argument instead of Outer.func – that breaks recording (if a function were injected, it’d be an unbound method and require an instance of “Outer” as its first argument, rather than a comparator/validator).

Theoretically, I could mock out “Outer” completely for its caller. However, setting up the expectations there would probably be more code, and not reusable elsewhere – any similar case/project would also have to reimplement “Outer” (or its equivalent) as a mock.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-16T22:22:07+00:00Added an answer on May 16, 2026 at 10:22 pm

    Given an object A, which contains a
    callable object B, is there a way to
    determine “A” from inside
    B.call()?

    Not in the general case, i.e., with the unbounded generality you require in this text — unless B keeps a reference to A in some way, Python most surely doesn’t keep it on B‘s behalf.

    For your intended use case, it’s even worse: it wouldn’t help even if B itself did keep a reference to A (as a method object would to its class), since you’re trampling all over B without recourse with that setattr, which is equivalent to an assignment. There is no trace left in class Outer that, back in happier times, it had a func attribute with certain characteristics: that attribute is no more, obliterated by your setattr.

    This isn’t really dependency injection (a design pattern requiring cooperation from the injected-into object), it’s monkey patching, one of my pet peeves, and its destructive, non-recoverable nature (that you’re currently struggling with) is part of why I peeve about it.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

No related questions found

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.