44import importlib
55import os
66import os .path
7- import shutil
87import site
98import subprocess
109import sys
@@ -90,8 +89,38 @@ class PythonPluginLoader(PluginLoader):
9089
9190 def __init__ (self , server : Server ):
9291 PluginLoader .__init__ (self , server )
93- self ._invalidate_caches ()
9492 self ._plugins : list [Plugin ] = []
93+ self ._uninstall_plugins ()
94+ self ._invalidate_caches ()
95+
96+ def __del__ (self ) -> None :
97+ self ._uninstall_plugins ()
98+
99+ @staticmethod
100+ def _find_plugin_eps () -> list [EntryPoint ]:
101+ return [
102+ ep
103+ for ep in entry_points (group = "endstone" )
104+ if ep .dist is not None and ep .dist .name .replace ("_" , "-" ).startswith ("endstone-" )
105+ ]
106+
107+ @staticmethod
108+ def _uninstall_plugins () -> None :
109+ dists = [ep .dist .name for ep in PythonPluginLoader ._find_plugin_eps ()] # type: ignore[union-attr]
110+ if not dists :
111+ return
112+ subprocess .run (
113+ [
114+ sys .executable ,
115+ "-m" ,
116+ "pip" ,
117+ "uninstall" ,
118+ * dists ,
119+ "-y" ,
120+ "--quiet" ,
121+ "--disable-pip-version-check" ,
122+ ],
123+ )
95124
96125 def _invalidate_caches (self ) -> None :
97126 importlib .invalidate_caches ()
@@ -102,21 +131,8 @@ def _invalidate_caches(self) -> None:
102131 self ._prefix = os .path .join ("plugins" , ".local" )
103132 for site_dir in site .getsitepackages (prefixes = [self ._prefix ]):
104133 site .addsitedir (site_dir )
105- if (
106- os .path .exists (site_dir )
107- and os .path .commonpath ([site_dir , self ._prefix ]) == self ._prefix
108- and site_dir != self ._prefix
109- ):
110- for directory in os .listdir (site_dir ):
111- if not os .path .isdir (os .path .join (site_dir , directory )):
112- continue
113- if directory .startswith ("endstone_" ) or directory .startswith ("~" ):
114- shutil .rmtree (os .path .join (site_dir , directory ))
115134
116135 def load_plugin (self , file : str ) -> Plugin | None : # type: ignore[override]
117- env = os .environ .copy ()
118- env .pop ("LD_PRELOAD" , "" )
119-
120136 dist_name : str | None = pkginfo .Wheel (file ).name
121137 if dist_name is None :
122138 raise ValueError (f"Could not determine package name from { file } " )
@@ -133,7 +149,7 @@ def load_plugin(self, file: str) -> Plugin | None: # type: ignore[override]
133149 "--no-warn-script-location" ,
134150 "--disable-pip-version-check" ,
135151 ],
136- env = env ,
152+
137153 )
138154
139155 eps = distribution (dist_name ).entry_points .select (group = "endstone" )
@@ -148,8 +164,7 @@ def load_plugins(self, directory: str) -> list[Plugin]:
148164 loaded_plugins = []
149165
150166 if not self ._plugins :
151- eps = entry_points (group = "endstone" )
152- for ep in eps :
167+ for ep in self ._find_plugin_eps ():
153168 plugin = self ._load_plugin_from_ep (ep )
154169 if plugin :
155170 loaded_plugins .append (plugin )
@@ -162,17 +177,8 @@ def load_plugins(self, directory: str) -> list[Plugin]:
162177 return loaded_plugins
163178
164179 def _load_plugin_from_ep (self , ep : EntryPoint ) -> Plugin | None :
165- # enforce naming convention
166180 if ep .dist is None :
167181 return None
168- if not ep .dist .name .replace ("_" , "-" ).startswith ("endstone-" ):
169- self .server .logger .error (
170- f"Error occurred when trying to load plugin from entry point '{ ep .name } ': Invalid name."
171- )
172- self .server .logger .error (
173- f"The name of distribution ({ ep .dist .name } ) does not start with 'endstone-' or 'endstone_'."
174- )
175- return None
176182
177183 dist_name = "endstone-" + ep .name .replace ("_" , "-" )
178184 if ep .dist .name .replace ("_" , "-" ) != dist_name :
0 commit comments