Skip to content

Commit 9aca393

Browse files
author
Mickaël Schoentgen
committed
Mac: Fix memory leak (fix BoboTiG#24)
1 parent a0df61b commit 9aca393

5 files changed

Lines changed: 28 additions & 10 deletions

File tree

CHANGELOG

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ dev 2017/xx/xx
88
- tests: a lot of tests added for better coverage
99
- MSS: possibility to use custom class to handle screen shot data
1010
- Mac: handle screenshot's width not divisible by 16 (fix #14, #19, #21)
11+
- Mac: fix memory leak (fix #24)
1112
- Linux: handle bad display value
1213
- Windows: Take into account zoom factor for high-DPI displays (fix #20)
1314

docs/source/developers.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ How to test?
3131

3232
Enable the developer mode::
3333

34-
$ sudo python setup.py develop
34+
$ python -m pip install -e .
3535

3636
Lauch the test suit::
3737

mss/darwin.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ def _set_argtypes(self):
9898
self.core.CFDataGetBytePtr.argtypes = [ctypes.c_void_p]
9999
self.core.CFDataGetLength.argtypes = [ctypes.c_void_p]
100100
self.core.CGDataProviderRelease.argtypes = [ctypes.c_void_p]
101+
self.core.CFRelease.argtypes = [ctypes.c_void_p]
101102

102103
def _set_restypes(self):
103104
# type: () -> None
@@ -114,6 +115,7 @@ def _set_restypes(self):
114115
self.core.CFDataGetBytePtr.restype = ctypes.c_void_p
115116
self.core.CFDataGetLength.restype = ctypes.c_uint64
116117
self.core.CGDataProviderRelease.restype = ctypes.c_void_p
118+
self.core.CFRelease.restype = ctypes.c_void_p
117119

118120
@property
119121
def monitors(self):
@@ -183,12 +185,13 @@ def grab(self, monitor):
183185
'CoreGraphics.CGWindowListCreateImage() failed.', locals())
184186

185187
prov = self.core.CGImageGetDataProvider(image_ref)
186-
data = self.core.CGDataProviderCopyData(prov)
187-
data_ref = self.core.CFDataGetBytePtr(data)
188-
buf_len = self.core.CFDataGetLength(data)
189-
data = ctypes.cast(data_ref, ctypes.POINTER(ctypes.c_ubyte * buf_len))
190-
data = data.contents
188+
copy_data = self.core.CGDataProviderCopyData(prov)
189+
data_ref = self.core.CFDataGetBytePtr(copy_data)
190+
buf_len = self.core.CFDataGetLength(copy_data)
191+
raw = ctypes.cast(data_ref, ctypes.POINTER(ctypes.c_ubyte * buf_len))
192+
data = bytearray(raw.contents)
191193
self.core.CGDataProviderRelease(prov)
194+
self.core.CFRelease(copy_data)
192195

193196
if rounded_width != monitor['width']:
194197
data = self.resize(data, monitor)

tests/test_gnu_linux.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,13 @@ def test_factory_systems(monkeypatch):
3131
monkeypatch.setattr(platform, 'system', lambda: 'LINUX')
3232
sct = mss.mss()
3333
assert isinstance(sct, MSSBase)
34+
monkeypatch.undo()
3435

3536
# macOS
3637
monkeypatch.setattr(platform, 'system', lambda: 'Darwin')
3738
with pytest.raises(ScreenShotError) as exc:
3839
mss.mss()
40+
monkeypatch.undo()
3941
if not PY3:
4042
error = exc.value[1]['self']
4143
else:
@@ -47,6 +49,7 @@ def test_factory_systems(monkeypatch):
4749
with pytest.raises(ValueError):
4850
# wintypes.py:19: ValueError: _type_ 'v' not supported
4951
mss.mss()
52+
monkeypatch.undo()
5053

5154

5255
def test_implementation(monkeypatch, is_travis):

tests/test_implementation.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def test_repr(sct):
6363
assert repr(img) == repr(ref)
6464

6565

66-
def test_factory_basics(monkeypatch):
66+
def test_factory(monkeypatch):
6767
# Current system
6868
with mss.mss() as sct:
6969
assert isinstance(sct, MSSBase)
@@ -72,13 +72,24 @@ def test_factory_basics(monkeypatch):
7272
monkeypatch.setattr(platform, 'system', lambda: 'Chuck Norris')
7373
with pytest.raises(ScreenShotError) as exc:
7474
mss.mss()
75+
monkeypatch.undo()
76+
7577
if not PY3:
7678
error = exc.value[0]
7779
else:
7880
error = exc.value.args[0]
7981
assert error == 'System not (yet?) implemented.'
8082

8183

82-
def test_python_call():
83-
# __import__('mss.__main__')
84-
pytest.skip('Dunno how to test mss/__main__.py.')
84+
def test_python_call(monkeypatch):
85+
import mss.__main__
86+
mss.__main__.main()
87+
88+
def raise_():
89+
raise ScreenShotError()
90+
91+
pytest.skip('Not working for now.')
92+
monkeypatch.setattr(mss.mss, '__init__', raise_)
93+
with pytest.raises(ScreenShotError):
94+
mss.mss()
95+
monkeypatch.undo()

0 commit comments

Comments
 (0)