-
Notifications
You must be signed in to change notification settings - Fork 49
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
201 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import os | ||
import sys | ||
from functools import wraps | ||
from pathlib import Path | ||
from time import time | ||
from typing import Optional | ||
|
||
|
||
def rate_limited(t): | ||
"""Prevent a function from being called more than once in `t` seconds.""" | ||
|
||
def decorator(f): | ||
last = [0.0] | ||
|
||
@wraps(f) | ||
def wrapper(*args, **kwargs): | ||
if last[0] and (time() - last[0] < t): | ||
return | ||
last[0] = time() | ||
return f(*args, **kwargs) | ||
|
||
return wrapper | ||
|
||
return decorator | ||
|
||
|
||
# modified from appdirs: https://github.com/ActiveState/appdirs | ||
# License: MIT | ||
def user_cache_dir( | ||
appname: Optional[str] = "magicgui", version: Optional[str] = None | ||
) -> Path: | ||
r"""Return full path to the user-specific cache dir for this application. | ||
Typical user cache directories are: | ||
Mac OS X: ~/Library/Caches/<AppName> | ||
Unix: ~/.cache/<AppName> (XDG default) | ||
Win XP: C:\Documents and Settings\<username>\Local Settings\Application Data\<AppName>\Cache # noqa | ||
Vista: C:\Users\<username>\AppData\Local\<AppName>\Cache | ||
Parameters | ||
---------- | ||
appname : str, optional | ||
Name of application. If None, just the system directory is returned. | ||
by default "magicgui" | ||
version : str, optional | ||
an optional version path element to append to the path. You might want to use | ||
this if you want multiple versions of your app to be able to run independently. | ||
If used, this would typically be "<major>.<minor>". Only applied when appname is | ||
present. | ||
Returns | ||
------- | ||
str | ||
Full path to the user-specific cache dir for this application. | ||
""" | ||
if sys.platform.startswith("java"): | ||
import platform | ||
|
||
os_name = platform.java_ver()[3][0] | ||
if os_name.startswith("Windows"): # "Windows XP", "Windows 7", etc. | ||
system = "win32" | ||
elif os_name.startswith("Mac"): # "Mac OS X", etc. | ||
system = "darwin" | ||
else: # "Linux", "SunOS", "FreeBSD", etc. | ||
# Setting this to "linux2" is not ideal, but only Windows or Mac | ||
# are actually checked for and the rest of the module expects | ||
# *sys.platform* style strings. | ||
system = "linux2" | ||
else: | ||
system = sys.platform | ||
|
||
home = Path.home() | ||
if system == "win32": | ||
_epath = os.getenv("LOCALAPPDATA") | ||
path = Path(_epath).resolve() if _epath else home / "AppData" / "Local" | ||
if appname: | ||
path = path / appname / "Cache" | ||
elif system == "darwin": | ||
path = home / "Library" / "Caches" | ||
if appname: | ||
path = path / appname | ||
else: | ||
_epath = os.getenv("XDG_CACHE_HOME") | ||
path = Path(_epath) if _epath else home / ".cache" | ||
if appname: | ||
path = path / appname | ||
if appname and version: | ||
path = path / version | ||
return path |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import time | ||
from unittest.mock import patch | ||
|
||
from magicgui._util import user_cache_dir | ||
from magicgui.widgets import FunctionGui | ||
|
||
|
||
def test_user_cache_dir(): | ||
ucd = user_cache_dir() | ||
import sys | ||
from pathlib import Path | ||
|
||
home = Path.home().resolve() | ||
if sys.platform == "win32": | ||
assert str(ucd) == str(home / "AppData" / "Local" / "magicgui" / "Cache") | ||
elif sys.platform == "darwin": | ||
assert str(ucd) == str(home / "Library" / "Caches" / "magicgui") | ||
else: | ||
assert str(ucd) == str(home / ".cache" / "magicgui") | ||
|
||
|
||
def test_persistence(tmp_path): | ||
"""Test that we can persist values across instances.""" | ||
|
||
def _my_func(x: int, y="hello"): | ||
... | ||
|
||
with patch("magicgui._util.user_cache_dir", lambda: tmp_path): | ||
fg = FunctionGui(_my_func, persist=True) | ||
assert str(tmp_path) in str(fg._dump_path) | ||
assert fg.x.value == 0 | ||
fg.x.value = 10 | ||
time.sleep(0.26) # required by rate limit | ||
fg.y.value = "world" | ||
|
||
# second instance should match values of first | ||
fg2 = FunctionGui(_my_func, persist=True) | ||
assert fg2.x.value == 10 | ||
assert fg2.y.value == "world" | ||
assert fg2.__signature__ == fg.__signature__ | ||
assert fg2 is not fg |