Skip to content

Conversation

@smacke
Copy link

@smacke smacke commented Nov 15, 2024

This PR fixes a corner case when using ipytest with certain IPython environments. Some environments, such as Databricks, use an IPython feature where the user_ns of the interactive shell is specified ahead of time. Because this user_ns doubles as the main module's __dict__, the official module type cannot be used, since __dict__ is a read-only attribute. To work around this, IPython uses a fake module type called DummyMod to handle this case. However, instances of DummyMod do not pass the isinstance check added in c6a5290. To fix, check if we've imported the module that contains DummyMod, and if so, add DummyMod to the isinstance check.

Test plan: verified manually.

@smacke smacke force-pushed the dummymod-fixture-fix branch from 6021cf7 to 9c9c592 Compare November 15, 2024 01:32
Copy link
Member

@nicoddemus nicoddemus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @smacke for the PR.

I'm hesitant to add this hack to the collection code.

Wouldn't make more sense for IPython to change DummyMod to subclass from types.ModuleType? This would not need changes in pytest, while it would also be compatible with anything else that might inspect the module.

@smacke
Copy link
Author

smacke commented Nov 20, 2024

Yeah, agree fixing in IPython makes more sense.

@smacke smacke closed this Nov 20, 2024
Carreau added a commit to ipython/ipython that referenced this pull request Feb 23, 2025
… user_ns (#14754)

## What changes are proposed in this pull request?
Some IPython apps, such as the one used in Databricks, need to seed the
shell with a custom user namespace before it is actually created. This
means the main module used by ipython can’t be a normal ModuleType
(which doesn’t support overwriting __dict__) but instead a custom
“DummyMod”. DummyMod isn’t considered an instance of ModuleType, which
can mess up tools like ipytest + pytest -- see, for example,
pytest-dev/pytest#12965.

To fix, in this PR we create a helper function that generates a
`ModuleType` subclass on-the-fly and that uses the user namespace
provided a priori as its `__dict__`. Note that `ModuleType.__dict__` is
read-only, which is probably why IPython originally created DummyMod. To
get around that, we create a `__dict__` property and use custom getters
/ setters to delegate to the user_ns we pass in.

Searching around, it seems like `DummyMod` / `FakeModule` may have
caused some pain points in the past, e.g. around pickling
(#384,
#112) -- still trying to
determine if this change can help with that.

## How is this tested?
Manual + pre-merge
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants