6
6
import subprocess
7
7
from distutils .cmd import Command
8
8
from distutils .errors import (
9
- CompileError ,
10
- DistutilsExecError , DistutilsFileError , DistutilsPlatformError )
9
+ CompileError , DistutilsExecError , DistutilsFileError ,
10
+ DistutilsPlatformError , DistutilsSetupError )
11
11
12
- import semver
12
+ import semantic_version
13
13
14
14
from . import patch # noqa
15
15
@@ -25,7 +25,7 @@ class RustExtension:
25
25
the full name of the extension, including any packages -- ie.
26
26
*not* a filename or pathname, but Python dotted name
27
27
path : string
28
- path to the cargo.toml manifest
28
+ path to the cargo.toml manifest file
29
29
args : [string]
30
30
a list of extra argumenents to be passed to cargo.
31
31
features : [string]
@@ -53,26 +53,31 @@ def __init__(self, name, path,
53
53
54
54
self .features = [s .strip () for s in features ]
55
55
56
- @staticmethod
57
- def get_rust_version ():
58
- env = os .environ .copy ()
59
- try :
60
- output = subprocess .check_output (["rustc" , "-V" ], env = env )
61
- return output .split (' ' )[1 ]
62
- except subprocess .CalledProcessError :
63
- return None
64
- except OSError :
56
+ def get_rust_version (self ):
57
+ if self .rust_version is None :
65
58
return None
59
+ try :
60
+ return semantic_version .Spec (self .rust_version )
61
+ except :
62
+ raise DistutilsSetupError (
63
+ 'Can not parse rust compiler version: %s' , self .rust_version )
66
64
67
65
68
- class build_rust (Command ):
69
- """
70
- Command for building rust crates via cargo.
66
+ def get_rust_version ():
67
+ try :
68
+ output = subprocess .check_output (["rustc" , "-V" ])
69
+ if isinstance (output , bytes ):
70
+ output = output .decode ('latin-1' )
71
+ return semantic_version .Version (output .split (' ' )[1 ], partial = True )
72
+ except (subprocess .CalledProcessError , OSError ):
73
+ raise DistutilsPlatformError ('Can not find Rust compiler' )
74
+ except Exception as exc :
75
+ raise DistutilsPlatformError (
76
+ 'Can not get rustc version: %s' % str (exc ))
71
77
72
- Don't use this directly; use the build_rust_cmdclass
73
- factory method.
74
- """
75
- description = "build rust crates into Python extensions"
78
+
79
+ class build_rust (Command ):
80
+ """ Command for building rust crates via cargo. """
76
81
77
82
user_options = [
78
83
('inplace' , 'i' ,
@@ -140,7 +145,7 @@ def build_extension(self, ext):
140
145
print (output , file = sys .stderr )
141
146
142
147
# Find the shared library that cargo hopefully produced and copy
143
- # it into the build directory as if it were produced by build_cext .
148
+ # it into the build directory as if it were produced by build_ext .
144
149
if ext .debug :
145
150
suffix = "debug"
146
151
else :
@@ -179,15 +184,16 @@ def build_extension(self, ext):
179
184
shutil .copyfile (dylib_path , ext_path )
180
185
181
186
def run (self ):
182
- version = RustExtension .get_rust_version ()
183
- if self .extensions and version is None :
184
- raise DistutilsPlatformError ('Can not find Rust compiler' )
187
+ if not self .extensions :
188
+ return
189
+
190
+ version = get_rust_version ()
185
191
186
192
for ext in self .extensions :
187
- if ext . rust_version is not None :
188
- if not semver . match ( version , ext . rust_version ) :
189
- raise DistutilsPlatformError (
190
- "Rust %s does not match extension requirenment %s" % (
191
- version , ext .rust_version ))
193
+ rust_version = ext . get_rust_version ()
194
+ if rust_version is not None and version not in rust_version :
195
+ raise DistutilsPlatformError (
196
+ "Rust %s does not match extension requirenment %s" % (
197
+ version , ext .rust_version ))
192
198
193
199
self .build_extension (ext )
0 commit comments