@@ -102,6 +102,9 @@ def show_versions(file=sys.stdout):
102
102
- System information (Python version, Operating System)
103
103
- Core dependency versions (NumPy, Pandas, Xarray, etc)
104
104
- GMT library information
105
+
106
+ It also warns users if the installed Ghostscript version has serious bugs or is
107
+ incompatible with the installed GMT version.
105
108
"""
106
109
107
110
import importlib
@@ -110,8 +113,18 @@ def show_versions(file=sys.stdout):
110
113
import subprocess
111
114
112
115
from packaging .requirements import Requirement
116
+ from packaging .version import Version
117
+
118
+ def _get_clib_info () -> dict :
119
+ """
120
+ Return information about the GMT shared library.
121
+ """
122
+ from pygmt .clib import Session
113
123
114
- def _get_module_version (modname ):
124
+ with Session () as ses :
125
+ return ses .info
126
+
127
+ def _get_module_version (modname : str ) -> str | None :
115
128
"""
116
129
Get version information of a Python module.
117
130
"""
@@ -128,17 +141,19 @@ def _get_module_version(modname):
128
141
except ImportError :
129
142
return None
130
143
131
- def _get_ghostscript_version ():
144
+ def _get_ghostscript_version () -> str | None :
132
145
"""
133
- Get ghostscript version.
146
+ Get Ghostscript version.
134
147
"""
135
- os_name = sys .platform
136
- if os_name .startswith (("linux" , "freebsd" , "darwin" )):
137
- cmds = ["gs" ]
138
- elif os_name == "win32" :
139
- cmds = ["gswin64c.exe" , "gswin32c.exe" ]
140
- else :
141
- return None
148
+ match sys .platform :
149
+ case "linux" | "darwin" :
150
+ cmds = ["gs" ]
151
+ case os_name if os_name .startswith ("freebsd" ):
152
+ cmds = ["gs" ]
153
+ case "win32" :
154
+ cmds = ["gswin64c.exe" , "gswin32c.exe" ]
155
+ case _:
156
+ return None
142
157
143
158
for gs_cmd in cmds :
144
159
if (gsfullpath := shutil .which (gs_cmd )) is not None :
@@ -147,24 +162,53 @@ def _get_ghostscript_version():
147
162
).strip ()
148
163
return None
149
164
165
+ def _check_ghostscript_version (gs_version : str ) -> str | None :
166
+ """
167
+ Check if the Ghostscript version is compatible with GMT versions.
168
+ """
169
+ match Version (gs_version ):
170
+ case v if v < Version ("9.53" ):
171
+ return (
172
+ f"Ghostscript v{ gs_version } is too old and may have serious bugs. "
173
+ "Please consider upgrading your Ghostscript."
174
+ )
175
+ case v if Version ("10.00" ) <= v < Version ("10.02" ):
176
+ return (
177
+ f"Ghostscript v{ gs_version } has known bugs. "
178
+ "Please consider upgrading to version v10.02 or later."
179
+ )
180
+ case v if v >= Version ("10.02" ):
181
+ from pygmt .clib import __gmt_version__
182
+
183
+ if Version (__gmt_version__ ) < Version ("6.5.0" ):
184
+ return (
185
+ f"GMT v{ __gmt_version__ } doesn't support Ghostscript "
186
+ "v{gs_version}. Please consider upgrading to GMT>=6.5.0 or "
187
+ "downgrading to Ghostscript v9.56."
188
+ )
189
+ return None
190
+
150
191
sys_info = {
151
192
"python" : sys .version .replace ("\n " , " " ),
152
193
"executable" : sys .executable ,
153
194
"machine" : platform .platform (),
154
195
}
155
-
156
196
deps = [Requirement (v ).name for v in importlib .metadata .requires ("pygmt" )]
197
+ gs_version = _get_ghostscript_version ()
198
+
199
+ lines = []
200
+ lines .append ("PyGMT information:" )
201
+ lines .append (f" version: { __version__ } " )
202
+ lines .append ("System information:" )
203
+ lines .extend ([f" { key } : { val } " for key , val in sys_info .items ()])
204
+ lines .append ("Dependency information:" )
205
+ lines .extend ([f" { modname } : { _get_module_version (modname )} " for modname in deps ])
206
+ lines .append (f" ghostscript: { gs_version } " )
207
+ lines .append ("GMT library information:" )
208
+ lines .extend ([f" { key } : { val } " for key , val in _get_clib_info ().items ()])
209
+
210
+ if warnmsg := _check_ghostscript_version (gs_version ):
211
+ lines .append ("WARNING:" )
212
+ lines .append (f" { warnmsg } " )
157
213
158
- print ("PyGMT information:" , file = file )
159
- print (f" version: { __version__ } " , file = file )
160
-
161
- print ("System information:" , file = file )
162
- for key , val in sys_info .items ():
163
- print (f" { key } : { val } " , file = file )
164
-
165
- print ("Dependency information:" , file = file )
166
- for modname in deps :
167
- print (f" { modname } : { _get_module_version (modname )} " , file = file )
168
- print (f" ghostscript: { _get_ghostscript_version ()} " , file = file )
169
-
170
- print_clib_info (file = file )
214
+ print ("\n " .join (lines ), file = file )
0 commit comments