Conversation
See also BoboTiG/python-mss issue BoboTiG#486. The user will always work with a single class: mss.MSS. Differences in implementation, such as platform or capture strategy, are hidden in an internal implementation object held by the mss.MSS object. This allows us to change the implementation, with arbitrary class hierarchies, without worrying about preserving compatibility with internal class names. This deprecates the existing `mss` factory function, although it can easily be kept for as long as needed to give users time to adapt. It also deprecates the existing `mss.{platform}.MSS` types. These are exposed to the user, so somebody calling `mss.{platform}.MSS()` in 10.x can still reasonably expect to get a `mss.{platform}.MSS` object back. However, in 11.0, we can remove the type entirely, and either remove those symbols, or make them deprecated aliases for `mss.MSS`. Where possible, deprecated functionality emits a `DeprecationWarning`. However, note that these are ignored by default, unless triggered by code in `__main__`. Many of the API docs are removed, since this change removes much of the API surface. However, they are still in available for backwards-compatibility. This change adds tests for everything that was in the 10.1 docs, examples, etc, at least at a basic level: for instance, it tests that `mss.linux.MSS` still works as both a constructor and a type (for `isinstance`), and that `mss.linux.ZPIXMAP` still exists (it was listed in the 10.1 docs). The existing code, tests, and docs are changed to use `mss.MSS`.
The mss_impl fixture would add an implicit display= argument, regardless of platform. The code at that time would ignore it, but we should be (and in the previous commit, were) more strict. Change mss_impl to only use display= if appropriate, so we can be more strict in the future. In 10.1, these were allowed at all times, and ignored if the platform didn't use them. Emulate this behavior in mss.MSS (and mss.mss), with DeprecationWarnings, and test.
I'm pretty sure it's unnecessary there. Not sure why it was being done.
There was a problem hiding this comment.
Pull request overview
This PR refactors MSS to a strategy-based design where users primarily interact with a single public class (mss.MSS) while platform/backend differences are encapsulated in an internal implementation object. It also updates tests, demos, and documentation to align with the new API, while introducing compatibility/deprecation coverage for legacy import paths.
Changes:
- Introduce
mss.MSS+ internalMSSImplementationstrategy layer, and rework platform backends to implement the new internal interface. - Deprecate legacy construction patterns (top-level
mss.mss, and platform-specificmss.{platform}.MSS) and add compatibility tests. - Update docs/examples/tests/benchmarks/demos to use
mss.MSS, and adjust internals-facing tests for_impl.
Reviewed changes
Copilot reviewed 59 out of 59 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/tests/third_party/test_pil.py | Update PIL integration tests to type against mss.MSS. |
| src/tests/third_party/test_numpy.py | Update NumPy integration test to type against mss.MSS. |
| src/tests/test_xcb.py | Switch XCB tests to mss.MSS(backend=...) and assert _impl type. |
| src/tests/test_windows.py | Update Windows tests to new MSS and _impl internals. |
| src/tests/test_tools.py | Update tools tests typing from MSSBase to MSS. |
| src/tests/test_setup.py | Use sys.executable -m ... for build/twine invocations; include new compat tests in sdist list. |
| src/tests/test_save.py | Update save/shot tests typing to mss.MSS. |
| src/tests/test_primary_monitor.py | Update to mss.MSS usage and typing. |
| src/tests/test_macos.py | Update macOS tests to new _impl structure and monitor cache semantics. |
| src/tests/test_leaks.py | Update leak/regression tests to use mss.MSS. |
| src/tests/test_issue_220.py | Update issue regression test to mss.MSS. |
| src/tests/test_implementation.py | Adapt implementation/unit tests to new MSSImplementation and mss.MSS. |
| src/tests/test_gnu_linux.py | Update GNU/Linux backend tests for new strategy design and _impl access. |
| src/tests/test_get_pixels.py | Update get_pixels tests to import MSS/ScreenShot from top-level. |
| src/tests/test_find_monitors.py | Update monitor discovery tests typing to mss.MSS. |
| src/tests/test_compat_linux_api.py | New tests ensuring documented Linux symbols remain re-exported. |
| src/tests/test_compat_exports.py | New tests ensuring key top-level compatibility exports exist. |
| src/tests/test_compat_10_1.py | New tests for 10.1-style imports/constructors + deprecation warnings. |
| src/tests/test_cls_image.py | Update custom cls_image test typing to mss.MSS. |
| src/tests/conftest.py | Update mss_impl fixture to construct mss.MSS with backend selection. |
| src/tests/bench_grab_windows.py | Update benchmark script to use mss.MSS and _impl handles. |
| src/tests/bench_general.py | Update benchmark typing and construction to mss.MSS. |
| src/tests/bench_bgra2rgb.py | Update benchmark to use mss.MSS. |
| src/mss/windows.py | Introduce MSSImplWindows and a deprecated mss.windows.MSS wrapper. |
| src/mss/linux/xshmgetimage.py | Rename implementation to MSSImplXShmGetImage and adapt to new internal interface. |
| src/mss/linux/xlib.py | Rename implementation to MSSImplXlib and adapt cursor/grab/monitors to new interface. |
| src/mss/linux/xgetimage.py | Rename implementation to MSSImplXGetImage and adapt to new internal interface. |
| src/mss/linux/base.py | Rename base to MSSImplXCBBase and adjust monitors/cursor/grab helpers. |
| src/mss/linux/init.py | Provide deprecated mss.linux.MSS wrapper and Linux backend implementation chooser. |
| src/mss/factory.py | Deprecate mss.mss() factory to warn and return mss.MSS. |
| src/mss/darwin.py | Introduce MSSImplDarwin and deprecated mss.darwin.MSS wrapper. |
| src/mss/base.py | Add MSSImplementation and new public MSS that delegates to an internal _impl. |
| src/mss/main.py | Update CLI entry point to instantiate mss.MSS directly. |
| src/mss/init.py | Export MSS and ScreenShot at top-level alongside legacy exports. |
| README.md | Update quickstart snippet to from mss import MSS. |
| docs/source/usage.rst | Update usage docs to prefer mss.MSS and describe deprecated legacy entry points. |
| docs/source/index.rst | Update docs landing example to mss.MSS. |
| docs/source/examples/pil.py | Update example to use mss.MSS. |
| docs/source/examples/pil_pixels.py | Update example to use mss.MSS. |
| docs/source/examples/part_of_screen.py | Update example to use mss.MSS. |
| docs/source/examples/part_of_screen_monitor_2.py | Update example to use mss.MSS. |
| docs/source/examples/opencv_numpy.py | Update example to use mss.MSS. |
| docs/source/examples/linux_xshm_backend.py | Update example to use MSS(backend=...) instead of backend-class import. |
| docs/source/examples/linux_display_keyword.py | Update example to use mss.MSS(display=...). |
| docs/source/examples/from_pil_tuple.py | Update example to use mss.MSS. |
| docs/source/examples/fps.py | Update example to use mss.MSS. |
| docs/source/examples/fps_multiprocessing.py | Update example to use mss.MSS. |
| docs/source/examples/custom_cls_image.py | Update example to use mss.MSS. |
| docs/source/examples/callback.py | Update example to use mss.MSS. |
| docs/source/examples.rst | Update narrative examples to use mss.MSS. |
| docs/source/conf.py | Adjust comments and PROT_READ monkeypatch for docs build. |
| docs/source/api.rst | Reduce/remove large parts of API surface from rendered API docs. |
| demos/video-capture.py | Update demo typing + construction to mss.MSS. |
| demos/video-capture-simple.py | Update demo to use mss.MSS. |
| demos/tinytv-stream.py | Update demo to use mss.MSS. |
| demos/tinytv-stream-simple.py | Update demo to use mss.MSS. |
| demos/cat-detector.py | Update demo to use mss.MSS. |
| CHANGES.md | Document strategy refactor and new mss.MSS API. |
| CHANGELOG.md | Summarize new stable mss.MSS API and deprecation window. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| super().__init__(**kwargs) | ||
|
|
||
|
|
||
| def choose_impl(backend: str = "default", **kwargs: Any) -> MSSImplementation: |
There was a problem hiding this comment.
The public mss.linux.mss(...) factory appears to have been removed (replaced by choose_impl(...) which returns an internal MSSImplementation). This is a backwards-incompatible API change for callers using the documented Linux backend selector; consider reintroducing mss() as a deprecated wrapper that returns mss.MSS(backend=..., **kwargs) (or similar) while keeping choose_impl() internal.
| __all__ = () | ||
|
|
||
| class MSS(MSSXCBBase): | ||
|
|
||
| class MSSImplXGetImage(MSSImplXCBBase): |
There was a problem hiding this comment.
mss.linux.xgetimage used to expose a public MSS class (as shown by the removed class MSS(...)), but the module now only defines MSSImplXGetImage and sets __all__ = (). If you intend a deprecation period similar to mss.linux.MSS, consider adding back a deprecated MSS symbol (wrapper/alias) so from mss.linux.xgetimage import MSS continues to work during 10.x.
| """XCB backend using XGetImage requests on GNU/Linux. | ||
|
|
||
| .. seealso:: | ||
| :py:class:`mss.linux.base.MSSXCBBase` | ||
| Lists constructor parameters. |
There was a problem hiding this comment.
The docstring still references mss.linux.base.MSSXCBBase, but that type was renamed to MSSImplXCBBase. Update the .. seealso:: target to avoid broken Sphinx references / stale docs.
| @@ -36,11 +37,11 @@ class ShmStatus(enum.Enum): | |||
| UNAVAILABLE = enum.auto() # We know SHM GetImage is unusable; always use XGetImage. | |||
|
|
|||
|
|
|||
| class MSS(MSSXCBBase): | |||
| class MSSImplXShmGetImage(MSSImplXCBBase): | |||
| """XCB backend using XShmGetImage with an automatic XGetImage fallback. | |||
There was a problem hiding this comment.
Similar to xgetimage, this module previously exposed a public MSS class, but now only defines MSSImplXShmGetImage and __all__ = (). If maintaining import-path compatibility during the 10.x deprecation window is a goal, consider adding a deprecated MSS wrapper/alias so from mss.linux.xshmgetimage import MSS doesn't break.
| from mss.models import CFunctions, Monitor, Monitors | ||
|
|
||
| __all__ = ("MSS",) | ||
| __all__ = () | ||
|
|
There was a problem hiding this comment.
This module no longer exports a public MSS type (__all__ = () and the implementation class is now MSSImplXlib). Given older docs/examples and third-party code may still import mss.linux.xlib.MSS, consider providing a deprecated MSS alias/wrapper here (similar to the platform modules) for the 10.x transition period.
| For compatibility with existing code, platform-specific class names are also | ||
| still available in 10.2:: | ||
|
|
||
| # GNU/Linux | ||
| from mss.linux import MSS | ||
|
|
||
| Instance | ||
| ======== | ||
| # macOS | ||
| from mss.darwin import MSS | ||
|
|
||
| So the module can be used as simply as:: | ||
| # Microsoft Windows | ||
| from mss.windows import MSS |
There was a problem hiding this comment.
This section describes platform-specific MSS classes as “still available in 10.2”, but these constructors now emit DeprecationWarning and are planned for removal (per docstrings in mss.{platform}). Consider explicitly calling out that these imports/constructors are deprecated and that users should prefer mss.MSS to avoid warnings and future breakage.
See also BoboTiG/python-mss issue BoboTiG#486.
The user will always work with a single class:
mss.MSS. Differences in implementation, such as platform or capture strategy, are hidden in an internal implementation object held by the mss.MSS object.This allows us to change the implementation, with arbitrary class hierarchies, without worrying about preserving compatibility with internal class names.
This deprecates the existing
mssfactory function, although it can easily be kept for as long as needed to give users time to adapt.It also deprecates the existing
mss.{platform}.MSStypes. These are exposed to the user, so somebody callingmss.{platform}.MSS()in 10.x can still reasonably expect to get amss.{platform}.MSSobject back. However, in 11.0, we can remove the type entirely, and either remove those symbols, or make them deprecated aliases formss.MSS.Where possible, deprecated functionality emits a
DeprecationWarning. However, note that these are ignored by default, unless triggered by code in__main__.Many of the API docs are removed, since this change removes much of the API surface. However, they are still in available for backwards-compatibility.
This change adds tests for everything that was in the 10.1 docs, examples, etc, at least at a basic level: for instance, it tests that
mss.linux.MSSstill works as both a constructor and a type (forisinstance), and thatmss.linux.ZPIXMAPstill exists (it was listed in the 10.1 docs).The existing code, tests, and docs are changed to use
mss.MSS.