pkl-python 0.1.14__tar.gz → 0.1.15__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. {pkl-python-0.1.14 → pkl_python-0.1.15}/PKG-INFO +2 -2
  2. {pkl-python-0.1.14 → pkl_python-0.1.15}/pyproject.toml +13 -2
  3. pkl_python-0.1.15/src/pkl/VERSION +1 -0
  4. pkl_python-0.1.15/src/pkl/binary_manager.py +185 -0
  5. {pkl-python-0.1.14 → pkl_python-0.1.15}/src/pkl/server.py +6 -62
  6. {pkl-python-0.1.14 → pkl_python-0.1.15}/src/pkl_python.egg-info/PKG-INFO +2 -2
  7. {pkl-python-0.1.14 → pkl_python-0.1.15}/src/pkl_python.egg-info/SOURCES.txt +2 -1
  8. pkl_python-0.1.15/tests/test_binary.py +61 -0
  9. pkl-python-0.1.14/setup.py +0 -74
  10. pkl-python-0.1.14/src/pkl/VERSION +0 -1
  11. {pkl-python-0.1.14 → pkl_python-0.1.15}/LICENSE +0 -0
  12. {pkl-python-0.1.14 → pkl_python-0.1.15}/README.md +0 -0
  13. {pkl-python-0.1.14 → pkl_python-0.1.15}/setup.cfg +0 -0
  14. {pkl-python-0.1.14 → pkl_python-0.1.15}/src/pkl/__init__.py +0 -0
  15. {pkl-python-0.1.14 → pkl_python-0.1.15}/src/pkl/evaluator_manager.py +0 -0
  16. {pkl-python-0.1.14 → pkl_python-0.1.15}/src/pkl/evaluator_options.py +0 -0
  17. {pkl-python-0.1.14 → pkl_python-0.1.15}/src/pkl/msgapi.py +0 -0
  18. {pkl-python-0.1.14 → pkl_python-0.1.15}/src/pkl/parser.py +0 -0
  19. {pkl-python-0.1.14 → pkl_python-0.1.15}/src/pkl/reader.py +0 -0
  20. {pkl-python-0.1.14 → pkl_python-0.1.15}/src/pkl/utils.py +0 -0
  21. {pkl-python-0.1.14 → pkl_python-0.1.15}/src/pkl_gen_python.py +0 -0
  22. {pkl-python-0.1.14 → pkl_python-0.1.15}/src/pkl_python.egg-info/dependency_links.txt +0 -0
  23. {pkl-python-0.1.14 → pkl_python-0.1.15}/src/pkl_python.egg-info/entry_points.txt +0 -0
  24. {pkl-python-0.1.14 → pkl_python-0.1.15}/src/pkl_python.egg-info/requires.txt +0 -0
  25. {pkl-python-0.1.14 → pkl_python-0.1.15}/src/pkl_python.egg-info/top_level.txt +0 -0
  26. {pkl-python-0.1.14 → pkl_python-0.1.15}/tests/test_evaluator_manager.py +0 -0
  27. {pkl-python-0.1.14 → pkl_python-0.1.15}/tests/test_fixtures.py +0 -0
  28. {pkl-python-0.1.14 → pkl_python-0.1.15}/tests/test_load.py +0 -0
  29. {pkl-python-0.1.14 → pkl_python-0.1.15}/tests/test_parser.py +0 -0
  30. {pkl-python-0.1.14 → pkl_python-0.1.15}/tests/test_readers.py +0 -0
  31. {pkl-python-0.1.14 → pkl_python-0.1.15}/tests/test_server.py +0 -0
  32. {pkl-python-0.1.14 → pkl_python-0.1.15}/tests/test_trace.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pkl-python
3
- Version: 0.1.14
3
+ Version: 0.1.15
4
4
  Summary: Python library for Apple's PKL.
5
5
  Author-email: Jungwoo Yang <jwyang0213@gmail.com>
6
6
  License: MIT License
@@ -31,7 +31,7 @@ Project-URL: Source, https://github.com/jw-y/pkl-python
31
31
  Classifier: Programming Language :: Python :: 3
32
32
  Classifier: License :: OSI Approved :: MIT License
33
33
  Classifier: Operating System :: OS Independent
34
- Requires-Python: >=3.7
34
+ Requires-Python: >=3.8
35
35
  Description-Content-Type: text/markdown
36
36
  License-File: LICENSE
37
37
  Requires-Dist: msgpack>=1.0.8
@@ -1,5 +1,5 @@
1
1
  [build-system]
2
- requires = ["setuptools>=42", "wheel"]
2
+ requires = ["setuptools>=42", "wheel", "msgpack", "requests"]
3
3
  build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
@@ -11,7 +11,7 @@ authors = [
11
11
  ]
12
12
  license = { file = "LICENSE" }
13
13
  readme = "README.md"
14
- requires-python = ">=3.7"
14
+ requires-python = ">=3.8"
15
15
  classifiers = [
16
16
  "Programming Language :: Python :: 3",
17
17
  "License :: OSI Approved :: MIT License",
@@ -64,3 +64,14 @@ exclude = ["codegen/snippet-tests/output/*"]
64
64
 
65
65
  [tool.pytest.ini_options]
66
66
  addopts = "-ra -q"
67
+
68
+
69
+ [tool.cibuildwheel]
70
+ build = [
71
+ "*-macosx_x86_64",
72
+ "*-macosx_arm64",
73
+ "*-manylinux_aarch64",
74
+ "*-manylinux_x86_64",
75
+ #"*-musllinux_x86_64",
76
+ "*-win_amd64",
77
+ ]
@@ -0,0 +1 @@
1
+ 0.1.15
@@ -0,0 +1,185 @@
1
+ import argparse
2
+ import os
3
+ import platform
4
+ import stat
5
+ import subprocess
6
+ from functools import cache
7
+ from pathlib import Path
8
+
9
+ import requests
10
+
11
+ ARM_BINARIES = {
12
+ "darwin": "pkl-macos-aarch64",
13
+ "linux": "pkl-linux-aarch64",
14
+ }
15
+ AMD64_BINARIES = {
16
+ "darwin": "pkl-macos-amd64",
17
+ "linux": "pkl-linux-amd64",
18
+ "alpine-linux": "pkl-alpine-linux-amd64",
19
+ "windows": "pkl-windows-amd64.exe",
20
+ }
21
+ # PKL_VERSION = "0.26.3"
22
+ # BASE_PATH = "https://github.com/apple/pkl/releases/download/"
23
+
24
+
25
+ class BinaryManager:
26
+ def __init__(self, download_binary=True):
27
+ binary_fp = self.is_command_available() or self._downloaded_binary_path()
28
+ need_to_download = binary_fp is None
29
+ if download_binary and need_to_download:
30
+ binary_dir = self._default_bin_dir()
31
+ binary_url: str = self._determine_binary_url()
32
+ binary_fp = self.download_binary(binary_dir, binary_url)
33
+
34
+ self.binary_path = binary_fp
35
+
36
+ # self.binary_dir: Path = binary_dir or self._default_bin_dir()
37
+ # self.binary_name: str = binary_name or self._determine_binary_name()
38
+ # self.binary_path: Path = self.binary_dir / self.binary_name
39
+ # self.binary_base_url = BASE_PATH + PKL_VERSION + "/"
40
+ # self.binary_url = self.binary_base_url + self.binary_path.name
41
+
42
+ def _downloaded_binary_path(self):
43
+ binary_dir: Path = self._default_bin_dir()
44
+ if not binary_dir.exists():
45
+ return None
46
+ ls = list(binary_dir.iterdir())
47
+
48
+ if len(ls) == 0:
49
+ return None
50
+ elif len(ls) == 1:
51
+ return Path(ls[0])
52
+ else:
53
+ raise Exception("Something went wrong")
54
+
55
+ @cache
56
+ def get_latest_pkl_release_urls(self):
57
+ url = "https://api.github.com/repos/apple/pkl/releases/latest"
58
+ response = requests.get(url)
59
+ release = response.json()
60
+ assets = release["assets"]
61
+ urls = {a["name"]: a["browser_download_url"] for a in assets}
62
+ return urls
63
+
64
+ def is_command_available(self):
65
+ """
66
+ Check if a command is available in the system's PATH.
67
+ """
68
+ try:
69
+ if platform.system() == "Windows":
70
+ result = subprocess.run(
71
+ ["where", "pkl"],
72
+ check=True,
73
+ stdout=subprocess.PIPE,
74
+ stderr=subprocess.PIPE,
75
+ )
76
+ else:
77
+ result = subprocess.run(
78
+ ["which", "pkl"],
79
+ check=True,
80
+ stdout=subprocess.PIPE,
81
+ stderr=subprocess.PIPE,
82
+ )
83
+ return result.stdout.decode().splitlines()[0].strip()
84
+ except subprocess.CalledProcessError:
85
+ return None
86
+
87
+ def download_binary(self, binary_dir: Path, binary_url: str):
88
+ binary_dir.mkdir(exist_ok=True, parents=True)
89
+ return self._download_and_save_binary(binary_url, binary_dir)
90
+
91
+ def get_binary_filepath(self):
92
+ return str(self.binary_path)
93
+
94
+ def detect_system(self):
95
+ def is_alpine_linux():
96
+ return os.path.isfile("/etc/alpine-release")
97
+
98
+ def detect_processor_architecture():
99
+ architecture = platform.machine().lower()
100
+ if "arm" in architecture or "aarch64" in architecture:
101
+ return "ARM"
102
+ elif "x86_64" in architecture or "amd64" in architecture:
103
+ return "AMD64"
104
+ else:
105
+ return None
106
+
107
+ os_name = platform.system().lower()
108
+ if os_name == "linux" and is_alpine_linux():
109
+ os_name = "alpine-linux"
110
+ arch = detect_processor_architecture()
111
+ return os_name, arch
112
+
113
+ def _determine_binary_url(self) -> str:
114
+ os_name, arch = self.detect_system()
115
+ if arch == "ARM":
116
+ bin_name = ARM_BINARIES.get(os_name)
117
+ else:
118
+ bin_name = AMD64_BINARIES.get(os_name)
119
+
120
+ if bin_name is None:
121
+ raise OSError(
122
+ f"No compatible binary found for your system: {os_name}, {arch}"
123
+ )
124
+ name_to_url_map = self.get_latest_pkl_release_urls()
125
+ url = name_to_url_map[bin_name]
126
+ return url
127
+
128
+ @classmethod
129
+ def _default_bin_dir(cls) -> Path:
130
+ bin_dir = Path(__file__).parent / "bin"
131
+ return bin_dir
132
+
133
+ """
134
+ def download_all_binary(self):
135
+ download_dir = self._default_bin_dir()
136
+ download_dir.mkdir(exist_ok=True)
137
+ for filename in BINARIES.values():
138
+ url = self.binary_base_url + filename
139
+ self._download_and_save_binary(url, download_dir)
140
+ """
141
+
142
+ @classmethod
143
+ def _fetch_binary(cls, url):
144
+ response = requests.get(url)
145
+ response.raise_for_status()
146
+ return response.content
147
+
148
+ @classmethod
149
+ def _download_and_save_binary(
150
+ cls, url, target_dir: Path, filename=None, skip_exists=True
151
+ ) -> Path:
152
+ assert target_dir.is_dir()
153
+ content = cls._fetch_binary(url)
154
+
155
+ default_filename = Path(url).name
156
+ binary_fp = target_dir / (filename or default_filename)
157
+
158
+ if skip_exists and binary_fp.exists():
159
+ return binary_fp
160
+
161
+ with open(binary_fp, "wb") as f:
162
+ f.write(content)
163
+ print(f"Successfully installed {binary_fp}")
164
+ os.chmod(binary_fp, os.stat(binary_fp).st_mode | stat.S_IXUSR)
165
+ return binary_fp
166
+
167
+ def check(self):
168
+ cmd = [self.binary_path, "-v"]
169
+ result = subprocess.run(cmd, capture_output=True, text=True)
170
+ stdout = result.stdout
171
+ return stdout
172
+
173
+
174
+ def main():
175
+ parser = argparse.ArgumentParser()
176
+ parser.add_argument("--binary_dir")
177
+ args = parser.parse_args()
178
+
179
+ binary_dir = Path(args.binary_dir)
180
+ manager = BinaryManager(binary_dir=binary_dir)
181
+ manager.download_all_binary()
182
+
183
+
184
+ if __name__ == "__main__":
185
+ main()
@@ -1,23 +1,9 @@
1
1
  import atexit
2
2
  import os
3
- import platform
4
3
  import signal
5
- import stat
6
4
  import subprocess
7
- from pathlib import Path
8
5
 
9
6
  import msgpack
10
- import requests
11
-
12
- BINARIES = {
13
- ("darwin", "64bit"): "pkl-macos-amd64",
14
- ("darwin", "aarch64"): "pkl-macos-aarch64",
15
- ("linux", "64bit"): "pkl-linux-amd64",
16
- ("linux", "aarch64"): "pkl-linux-aarch64",
17
- ("linux", "64bit", "alpine"): "pkl-alpine-linux-amd64",
18
- }
19
- PKL_VERSION = "0.25.3"
20
- BASE_PATH = "https://github.com/apple/pkl/releases/download/"
21
7
 
22
8
 
23
9
  def preexec_function():
@@ -25,53 +11,6 @@ def preexec_function():
25
11
  signal.signal(signal.SIGHUP, signal.SIG_IGN)
26
12
 
27
13
 
28
- def detect_system():
29
- os_name = platform.system().lower()
30
- arch, _ = platform.architecture()
31
- return os_name, arch
32
-
33
-
34
- def is_alpine_linux():
35
- return os.path.isfile("/etc/alpine-release")
36
-
37
-
38
- def execute_binary(binary_path):
39
- subprocess.run([binary_path, "server"], check=True)
40
-
41
-
42
- def download_binary(file, target_fp):
43
- url = BASE_PATH + PKL_VERSION + "/" + file
44
- response = requests.get(url)
45
- with open(target_fp, "wb") as f:
46
- f.write(response.content)
47
-
48
-
49
- def get_binary_path():
50
- os_name, arch = detect_system()
51
- if os_name == "linux" and is_alpine_linux():
52
- os_name = "alpine"
53
- binary_key = (os_name, arch)
54
- if binary_key == ("linux", "64bit") and is_alpine_linux():
55
- binary_key += ("alpine",)
56
- bin_file = BINARIES.get(binary_key)
57
-
58
- if bin_file is None:
59
- raise OSError("No compatible binary found for your system.")
60
-
61
- bin_parent_path = (Path("~/.pkl/bin/") / PKL_VERSION).expanduser()
62
- binary_path = bin_parent_path / bin_file
63
-
64
- if not binary_path.exists():
65
- binary_path.parent.mkdir(exist_ok=True, parents=True)
66
- download_binary(bin_file, binary_path)
67
-
68
- current_permissions = os.stat(binary_path).st_mode
69
- new_permissions = current_permissions | stat.S_IXUSR
70
- os.chmod(binary_path, new_permissions)
71
-
72
- return binary_path
73
-
74
-
75
14
  _PROCESSES = []
76
15
 
77
16
 
@@ -86,7 +25,12 @@ atexit.register(terminate_processes)
86
25
 
87
26
  class PKLServer:
88
27
  def __init__(self, cmd=None, debug=False):
89
- self.cmd = cmd or [get_binary_path(), "server"]
28
+ from pkl.binary_manager import BinaryManager
29
+
30
+ manager = BinaryManager()
31
+ binary_path = manager.get_binary_filepath()
32
+
33
+ self.cmd = cmd or [binary_path, "server"]
90
34
  self.next_request_id = 1
91
35
  self.unpacker = msgpack.Unpacker()
92
36
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pkl-python
3
- Version: 0.1.14
3
+ Version: 0.1.15
4
4
  Summary: Python library for Apple's PKL.
5
5
  Author-email: Jungwoo Yang <jwyang0213@gmail.com>
6
6
  License: MIT License
@@ -31,7 +31,7 @@ Project-URL: Source, https://github.com/jw-y/pkl-python
31
31
  Classifier: Programming Language :: Python :: 3
32
32
  Classifier: License :: OSI Approved :: MIT License
33
33
  Classifier: Operating System :: OS Independent
34
- Requires-Python: >=3.7
34
+ Requires-Python: >=3.8
35
35
  Description-Content-Type: text/markdown
36
36
  License-File: LICENSE
37
37
  Requires-Dist: msgpack>=1.0.8
@@ -1,10 +1,10 @@
1
1
  LICENSE
2
2
  README.md
3
3
  pyproject.toml
4
- setup.py
5
4
  src/pkl_gen_python.py
6
5
  src/pkl/VERSION
7
6
  src/pkl/__init__.py
7
+ src/pkl/binary_manager.py
8
8
  src/pkl/evaluator_manager.py
9
9
  src/pkl/evaluator_options.py
10
10
  src/pkl/msgapi.py
@@ -18,6 +18,7 @@ src/pkl_python.egg-info/dependency_links.txt
18
18
  src/pkl_python.egg-info/entry_points.txt
19
19
  src/pkl_python.egg-info/requires.txt
20
20
  src/pkl_python.egg-info/top_level.txt
21
+ tests/test_binary.py
21
22
  tests/test_evaluator_manager.py
22
23
  tests/test_fixtures.py
23
24
  tests/test_load.py
@@ -0,0 +1,61 @@
1
+ import os
2
+ from pathlib import Path
3
+
4
+ import pytest
5
+
6
+ import pkl
7
+ from pkl.binary_manager import BinaryManager
8
+
9
+
10
+ def remove_pkl_from_path(monkeypatch):
11
+ manager = BinaryManager()
12
+ path = manager.is_command_available()
13
+ if path is None:
14
+ return
15
+ path = path.rsplit("/", 1)[0]
16
+ original_path = os.environ.get("PATH", "")
17
+ paths = original_path.split(os.pathsep)
18
+ paths = [p for p in paths if path not in p]
19
+ monkeypatch.setenv("PATH", os.pathsep.join(paths))
20
+
21
+
22
+ def remove_pkl_binary():
23
+ path = Path(pkl.__file__)
24
+ ls = list((path.parent / "bin").iterdir())
25
+ if len(ls) == 0:
26
+ return
27
+ assert len(ls) == 1
28
+ binary_path = ls[0]
29
+ os.remove(binary_path)
30
+ return binary_path
31
+
32
+
33
+ def test_latest_release():
34
+ manager = BinaryManager()
35
+ urls = manager.get_latest_pkl_release_urls()
36
+ assert len(urls) == 7
37
+
38
+
39
+ def test_without_download_binary():
40
+ manager = BinaryManager()
41
+ output = manager.check()
42
+ assert output.lower().startswith("pkl")
43
+
44
+
45
+ def test_download_binary(monkeypatch: pytest.MonkeyPatch):
46
+ remove_pkl_binary()
47
+ remove_pkl_from_path(monkeypatch)
48
+ manager = BinaryManager()
49
+ output = manager.check()
50
+ assert output.lower().startswith("pkl")
51
+
52
+ removed = remove_pkl_binary()
53
+ assert manager.binary_path == removed
54
+
55
+
56
+ def test_binary_file_exists():
57
+ manager = BinaryManager()
58
+ manager.is_command_available()
59
+
60
+ fp = manager.get_binary_filepath()
61
+ assert os.path.exists(fp), f"Binary file not found at {fp}"
@@ -1,74 +0,0 @@
1
- import os
2
- import platform
3
- import stat
4
- from pathlib import Path
5
-
6
- import setuptools
7
- from setuptools.command.install import install
8
-
9
- BINARIES = {
10
- ("darwin", "64bit"): "pkl-macos-amd64",
11
- ("darwin", "aarch64"): "pkl-macos-aarch64",
12
- ("linux", "64bit"): "pkl-linux-amd64",
13
- ("linux", "aarch64"): "pkl-linux-aarch64",
14
- ("linux", "64bit", "alpine"): "pkl-alpine-linux-amd64",
15
- }
16
- PKL_VERSION = "0.25.3"
17
- BASE_PATH = "https://github.com/apple/pkl/releases/download/"
18
-
19
-
20
- def detect_system():
21
- os_name = platform.system().lower()
22
- arch, _ = platform.architecture()
23
- return os_name, arch
24
-
25
-
26
- def is_alpine_linux():
27
- return os.path.isfile("/etc/alpine-release")
28
-
29
-
30
- def download_binary(file, target_fp):
31
- import requests
32
-
33
- url = BASE_PATH + PKL_VERSION + "/" + file
34
- response = requests.get(url)
35
- with open(target_fp, "wb") as f:
36
- f.write(response.content)
37
-
38
-
39
- def get_binary_path():
40
- os_name, arch = detect_system()
41
- if os_name == "linux" and is_alpine_linux():
42
- os_name = "alpine"
43
- binary_key = (os_name, arch)
44
- if binary_key == ("linux", "64bit") and is_alpine_linux():
45
- binary_key += ("alpine",)
46
- bin_file = BINARIES.get(binary_key)
47
-
48
- if bin_file is None:
49
- raise OSError("No compatible binary found for your system.")
50
-
51
- bin_parent_path = (Path("~/.pkl/bin/") / PKL_VERSION).expanduser()
52
- binary_path = bin_parent_path / bin_file
53
-
54
- if not binary_path.exists():
55
- binary_path.parent.mkdir(exist_ok=True, parents=True)
56
- download_binary(bin_file, binary_path)
57
-
58
- current_permissions = os.stat(binary_path).st_mode
59
- new_permissions = current_permissions | stat.S_IXUSR
60
- os.chmod(binary_path, new_permissions)
61
-
62
- return binary_path
63
-
64
-
65
- class CustomInstallCommand(install):
66
- def run(self):
67
- get_binary_path()
68
- install.run(self)
69
-
70
-
71
- setuptools.setup(
72
- cmdclass={"install": CustomInstallCommand},
73
- setup_requires=["requests"],
74
- )
@@ -1 +0,0 @@
1
- 0.1.14
File without changes
File without changes
File without changes