WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit df69451

Browse files
committed
refactoring
1 parent e6d2176 commit df69451

File tree

3 files changed

+111
-116
lines changed

3 files changed

+111
-116
lines changed

lib/pythonx.ex

Lines changed: 54 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,10 @@ defmodule Pythonx do
88

99
@moduledoc readme_docs
1010

11-
defstruct [
12-
:python_dl_path,
13-
:python_home_path,
14-
:python_executable_path,
15-
:sys_paths
16-
]
17-
1811
alias Pythonx.Object
1912

20-
@install_env_name "PYTHONX_FLAME_INIT_STATE"
13+
@install_env_name "PYTHONX_INIT_STATE"
2114

22-
@type init_state :: %__MODULE__{
23-
python_dl_path: String.t(),
24-
python_home_path: String.t(),
25-
python_executable_path: String.t(),
26-
sys_paths: [String.t()]
27-
}
2815
@type encoder :: (term(), encoder() -> Object.t())
2916

3017
@doc ~s'''
@@ -73,47 +60,84 @@ defmodule Pythonx do
7360
opts = Keyword.validate!(opts, force: false, uv_version: Pythonx.Uv.default_uv_version())
7461

7562
Pythonx.Uv.fetch(pyproject_toml, false, opts)
76-
init_state = Pythonx.Uv.init(pyproject_toml, false, Keyword.take(opts, [:uv_version]))
63+
install_paths = Pythonx.Uv.init(pyproject_toml, false, Keyword.take(opts, [:uv_version]))
64+
65+
init_state = %{
66+
type: :uv_init,
67+
pyproject_toml: pyproject_toml,
68+
opts: Keyword.drop(opts, [:force]),
69+
install_paths: install_paths
70+
}
71+
7772
:persistent_term.put(:pythonx_init_state, init_state)
7873
end
7974

80-
@spec init_state() :: init_state()
75+
@spec init_state() :: map()
8176
defp init_state() do
8277
:persistent_term.get(:pythonx_init_state)
8378
end
8479

85-
@doc ~s'''
86-
Fetches the pythonx init state from the system environment variable.
87-
'''
8880
@spec init_state_from_env() :: String.t() | nil
89-
def init_state_from_env(), do: System.get_env(@install_env_name)
81+
defp init_state_from_env(), do: System.get_env(@install_env_name)
9082

9183
@doc ~s'''
92-
Returns a map containing the environment variables required to initialize Pythonx.
84+
Returns a map with opaque environment variables to initialize Pythonx in
85+
the same way as the current initialization.
86+
87+
When those environment variables are set, Pythonx is initialized on boot.
88+
89+
In particular, this can be used to make Pythonx initialize on `FLAME` nodes.
9390
'''
9491
@spec install_env() :: map()
9592
def install_env() do
93+
init_state = init_state()
94+
95+
if init_state == nil do
96+
raise "before calling Pythonx.install_env/0, you must initialize Pythonx"
97+
end
98+
9699
init_state =
97-
init_state()
100+
init_state
98101
|> :erlang.term_to_binary()
99102
|> Base.encode64()
100103

101-
%{name: @install_env_name, value: init_state}
104+
%{@install_env_name => init_state}
102105
end
103106

104107
@doc ~s'''
105-
Returns a list of paths to copy to the flame runner.
108+
Returns a list of paths that `install_env/0` initialization depends on.
109+
110+
In particular, this can be used to make Pythonx initialize on `FLAME` nodes.
106111
'''
107112
@spec install_paths() :: list(String.t())
108113
def install_paths() do
109114
init_state = init_state()
110115

111-
[
112-
init_state.python_dl_path,
113-
init_state.python_executable_path
114-
] ++
115-
init_state.sys_paths ++
116-
Path.wildcard(Path.join(init_state.python_home_path, "**"), match_dot: true)
116+
if init_state == nil do
117+
raise "before calling Pythonx.install_paths/0, you must initialize Pythonx"
118+
end
119+
120+
init_state.install_paths
121+
end
122+
123+
@doc false
124+
def maybe_init_from_env() do
125+
case init_state_from_env() do
126+
nil ->
127+
:noop
128+
129+
init_state_env_value ->
130+
%{
131+
type: :uv_init,
132+
pyproject_toml: pyproject_toml,
133+
opts: opts
134+
} =
135+
init_state_env_value
136+
|> Base.decode64!()
137+
|> :erlang.binary_to_term()
138+
139+
uv_init(pyproject_toml, opts)
140+
end
117141
end
118142

119143
# Initializes the Python interpreter.
@@ -166,16 +190,6 @@ defmodule Pythonx do
166190
Pythonx.NIF.init(python_dl_path, python_home_path, python_executable_path, opts[:sys_paths])
167191
end
168192

169-
@spec init(init_state()) :: :ok
170-
def init(%__MODULE__{
171-
python_dl_path: python_dl_path,
172-
python_home_path: python_home_path,
173-
python_executable_path: python_executable_path,
174-
sys_paths: sys_paths
175-
}) do
176-
init(python_dl_path, python_home_path, python_executable_path, sys_paths: sys_paths)
177-
end
178-
179193
@doc ~S'''
180194
Evaluates the Python `code`.
181195

lib/pythonx/application.ex

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ defmodule Pythonx.Application do
1616
with {:ok, result} <- Supervisor.start_link(children, opts) do
1717
maybe_uv_init()
1818

19-
{:ok, result}
19+
{:ok, result}f
2020
end
2121
end
2222

@@ -31,18 +31,7 @@ defmodule Pythonx.Application do
3131
Pythonx.Uv.fetch(pyproject_toml, true, opts)
3232
defp maybe_uv_init(), do: Pythonx.Uv.init(unquote(pyproject_toml), true, unquote(opts))
3333
else
34-
defp maybe_uv_init() do
35-
case Pythonx.init_state_from_env() do
36-
nil ->
37-
:noop
38-
39-
init_state_env_value ->
40-
init_state_env_value
41-
|> Base.decode64!()
42-
|> :erlang.binary_to_term()
43-
|> Pythonx.init()
44-
end
45-
end
34+
defp maybe_uv_init(), do: Pythonx.maybe_init_from_env()
4635
end
4736

4837
defp enable_sigchld() do

lib/pythonx/uv.ex

Lines changed: 55 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ defmodule Pythonx.Uv do
6666
Initializes the interpreter using Python and dependencies previously
6767
fetched by `fetch/3`.
6868
"""
69-
@spec init(String.t(), boolean()) :: Pythonx.init_state()
69+
@spec init(String.t(), boolean()) :: list(String.t())
7070
def init(pyproject_toml, priv?, opts \\ []) do
7171
opts = Keyword.validate!(opts, uv_version: default_uv_version())
7272
project_dir = project_dir(pyproject_toml, priv?, opts[:uv_version])
@@ -95,69 +95,61 @@ defmodule Pythonx.Uv do
9595

9696
root_dir = Path.join(python_install_dir(priv?, opts[:uv_version]), versioned_dir_name)
9797

98-
init_state =
99-
case :os.type() do
100-
{:win32, _osname} ->
101-
# Note that we want the version-specific DLL, rather than the
102-
# "forwarder DLL" python3.dll, otherwise symbols cannot be
103-
# found directly.
104-
python_dl_path =
105-
root_dir
106-
|> Path.join("python3?*.dll")
107-
|> wildcard_one!()
108-
|> make_windows_slashes()
109-
110-
python_home_path = make_windows_slashes(root_dir)
111-
112-
python_executable_path =
113-
project_dir
114-
|> Path.join(".venv/Scripts/python.exe")
115-
|> make_windows_slashes()
116-
117-
venv_packages_path =
118-
project_dir
119-
|> Path.join(".venv/Lib/site-packages")
120-
|> make_windows_slashes()
121-
122-
%Pythonx{
123-
python_dl_path: python_dl_path,
124-
python_home_path: python_home_path,
125-
python_executable_path: python_executable_path,
126-
sys_paths: [venv_packages_path]
127-
}
128-
129-
{:unix, osname} ->
130-
dl_extension =
131-
case osname do
132-
:darwin -> ".dylib"
133-
:linux -> ".so"
134-
end
135-
136-
python_dl_path =
137-
root_dir
138-
|> Path.join("lib/libpython3.*" <> dl_extension)
139-
|> wildcard_one!()
140-
|> Path.expand()
141-
142-
python_home_path = root_dir
143-
144-
python_executable_path = Path.join(project_dir, ".venv/bin/python")
145-
146-
venv_packages_path =
147-
project_dir
148-
|> Path.join(".venv/lib/python3*/site-packages")
149-
|> wildcard_one!()
150-
151-
%Pythonx{
152-
python_dl_path: python_dl_path,
153-
python_home_path: python_home_path,
154-
python_executable_path: python_executable_path,
155-
sys_paths: [venv_packages_path]
156-
}
157-
end
98+
case :os.type() do
99+
{:win32, _osname} ->
100+
# Note that we want the version-specific DLL, rather than the
101+
# "forwarder DLL" python3.dll, otherwise symbols cannot be
102+
# found directly.
103+
python_dl_path =
104+
root_dir
105+
|> Path.join("python3?*.dll")
106+
|> wildcard_one!()
107+
|> make_windows_slashes()
108+
109+
python_home_path = make_windows_slashes(root_dir)
110+
111+
python_executable_path =
112+
project_dir
113+
|> Path.join(".venv/Scripts/python.exe")
114+
|> make_windows_slashes()
115+
116+
venv_packages_path =
117+
project_dir
118+
|> Path.join(".venv/Lib/site-packages")
119+
|> make_windows_slashes()
120+
121+
Pythonx.init(python_dl_path, python_home_path, python_executable_path,
122+
sys_paths: [venv_packages_path]
123+
)
124+
125+
{:unix, osname} ->
126+
dl_extension =
127+
case osname do
128+
:darwin -> ".dylib"
129+
:linux -> ".so"
130+
end
131+
132+
python_dl_path =
133+
root_dir
134+
|> Path.join("lib/libpython3.*" <> dl_extension)
135+
|> wildcard_one!()
136+
|> Path.expand()
137+
138+
python_home_path = root_dir
139+
140+
python_executable_path = Path.join(project_dir, ".venv/bin/python")
141+
142+
venv_packages_path =
143+
project_dir
144+
|> Path.join(".venv/lib/python3*/site-packages")
145+
|> wildcard_one!()
146+
147+
Pythonx.init(python_dl_path, python_home_path, python_executable_path,
148+
sys_paths: [venv_packages_path]
149+
)
150+
end
158151

159-
Pythonx.init(init_state)
160-
init_state
152+
[root_dir, project_dir]
161153
end
162154

163155
defp wildcard_one!(path) do

0 commit comments

Comments
 (0)