Skip to content

Move to a strategy implementation design#6

Closed
jholveck wants to merge 4 commits intomainfrom
strategy
Closed

Move to a strategy implementation design#6
jholveck wants to merge 4 commits intomainfrom
strategy

Conversation

@jholveck
Copy link
Copy Markdown
Owner

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.

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.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

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 + internal MSSImplementation strategy layer, and rework platform backends to implement the new internal interface.
  • Deprecate legacy construction patterns (top-level mss.mss, and platform-specific mss.{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:
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
Comment on lines +15 to +18
__all__ = ()

class MSS(MSSXCBBase):

class MSSImplXGetImage(MSSImplXCBBase):
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
Comment on lines 19 to 23
"""XCB backend using XGetImage requests on GNU/Linux.

.. seealso::
:py:class:`mss.linux.base.MSSXCBBase`
Lists constructor parameters.
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
Comment on lines 29 to 41
@@ -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.
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
Comment on lines +43 to 46
from mss.models import CFunctions, Monitor, Monitors

__all__ = ("MSS",)
__all__ = ()

Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
Comment on lines +23 to +33
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
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
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