2727# in .upstream/, the microsoft/playwright checkout at the commit in DRIVER_VERSION,
2828# and adds the Node.js binary of NODE_VERSION. The bundles are named after the
2929# commit (driver/playwright-<commit>-<suffix>.zip), so a roll builds new ones.
30+ #
31+ # A sdist build (python -m build --sdist) builds the "any" bundle the same way, but
32+ # without the Node.js binary, and ships it. A wheel built from the sdist packs that
33+ # bundle, so it is py3-none-any and runs with the Node.js of PLAYWRIGHT_NODEJS_PATH.
3034def read_driver_version () -> str :
3135 return (Path (__file__ ).parent / "DRIVER_VERSION" ).read_text ().strip ()
3236
3337
3438driver_version = read_driver_version ()
3539
40+ # The sdist unpacks with its metadata at the root; a checkout has none there.
41+ building_from_sdist = (Path (__file__ ).parent / "PKG-INFO" ).is_file ()
42+
43+ # "wheel" is the platform tag of the wheel name, as in base_wheel_bundles.
44+ sdist_bundle = {"wheel" : "any.whl" , "zip_name" : "any" }
45+
3646base_wheel_bundles = [
3747 {
3848 "wheel" : "macosx_10_13_x86_64.whl" ,
@@ -90,6 +100,7 @@ def read_driver_version() -> str:
90100 exit (0 )
91101
92102from setuptools import setup # noqa: E402
103+ from setuptools .command .sdist import sdist as SDistCommand # noqa: E402
93104
94105try :
95106 from auditwheel .wheeltools import InWheel
@@ -107,10 +118,18 @@ def extractall(zip: zipfile.ZipFile, path: str) -> None:
107118 os .chmod (extracted_path , attr )
108119
109120
121+ def driver_bundle_path (zip_name : str ) -> str :
122+ return f"driver/playwright-{ driver_version } -{ zip_name } .zip"
123+
124+
110125def ensure_driver_bundle (zip_name : str ) -> None :
111- destination_path = f"driver/playwright- { driver_version } - { zip_name } .zip"
126+ destination_path = driver_bundle_path ( zip_name )
112127 if os .path .exists (destination_path ):
113128 return
129+ if building_from_sdist :
130+ raise RuntimeError (
131+ f"Driver bundle { destination_path } is missing from the source distribution."
132+ )
114133 # Build only this platform's bundle, so that a wheel build downloads just the
115134 # one Node.js binary it needs.
116135 build_script = os .path .join (os .path .dirname (__file__ ), "scripts" , "build_driver.py" )
@@ -121,6 +140,16 @@ def ensure_driver_bundle(zip_name: str) -> None:
121140 )
122141
123142
143+ class PlaywrightSDistCommand (SDistCommand ):
144+ def make_distribution (self ) -> None :
145+ # The driver without Node.js, built from .upstream/ like the platform
146+ # bundles; the wheel build of the sdist packs it. The file list comes
147+ # from egg_info (the files that git tracks), so the bundle is added here.
148+ ensure_driver_bundle (sdist_bundle ["zip_name" ])
149+ self .filelist .append (driver_bundle_path (sdist_bundle ["zip_name" ]))
150+ super ().make_distribution ()
151+
152+
124153class PlaywrightBDistWheelCommand (BDistWheelCommand ):
125154 def run (self ) -> None :
126155 # setuptools copies the package into build/lib and keeps what is there: a
@@ -132,7 +161,9 @@ def run(self) -> None:
132161 self ._download_and_extract_local_driver ()
133162
134163 wheel = None
135- if os .getenv ("PLAYWRIGHT_TARGET_WHEEL" , None ):
164+ if building_from_sdist :
165+ wheel = sdist_bundle
166+ elif os .getenv ("PLAYWRIGHT_TARGET_WHEEL" , None ):
136167 wheel = list (
137168 filter (
138169 lambda wheel : wheel ["wheel" ]
@@ -162,14 +193,16 @@ def _build_wheel(
162193 # Although the build produces every platform's bundle, only this wheel's
163194 # target platform driver is extracted and packed below, so the wheel
164195 # stays single-platform.
165- zip_file = f"driver/playwright- { driver_version } - { wheel_bundle [' zip_name' ] } .zip"
196+ zip_file = driver_bundle_path ( wheel_bundle [" zip_name" ])
166197 extract_dir = f"driver/{ wheel_bundle ['zip_name' ]} "
167198 if os .path .exists (extract_dir ):
168199 shutil .rmtree (extract_dir )
169200 with zipfile .ZipFile (zip_file , "r" ) as zip :
170201 extractall (zip , extract_dir )
171202 wheel_location = without_platform + wheel_bundle ["wheel" ]
172- shutil .copy (base_wheel_location , wheel_location )
203+ # The base wheel is py3-none-any already: the "any" wheel adds to it in place.
204+ if wheel_location != base_wheel_location :
205+ shutil .copy (base_wheel_location , wheel_location )
173206 with zipfile .ZipFile (
174207 wheel_location , mode = "a" , compression = zipfile .ZIP_DEFLATED
175208 ) as zip :
@@ -183,7 +216,8 @@ def _build_wheel(
183216 "playwright/driver/README.md" ,
184217 f"{ wheel_bundle ['wheel' ]} driver package" ,
185218 )
186- os .remove (base_wheel_location )
219+ if wheel_location != base_wheel_location :
220+ os .remove (base_wheel_location )
187221 for whlfile in glob .glob (os .path .join (self .dist_dir , "*.whl" )):
188222 os .makedirs ("wheelhouse" , exist_ok = True )
189223 if InWheel :
@@ -197,26 +231,32 @@ def _build_wheel(
197231 def _download_and_extract_local_driver (
198232 self ,
199233 ) -> None :
200- zip_names_for_current_system = set (
201- map (
202- lambda wheel : wheel ["zip_name" ],
203- filter (
204- lambda wheel : wheel ["machine" ] == platform .machine ().lower ()
205- and wheel ["platform" ] == sys .platform ,
206- base_wheel_bundles ,
207- ),
234+ if building_from_sdist :
235+ zip_name = sdist_bundle ["zip_name" ]
236+ else :
237+ zip_names_for_current_system = set (
238+ map (
239+ lambda wheel : wheel ["zip_name" ],
240+ filter (
241+ lambda wheel : wheel ["machine" ] == platform .machine ().lower ()
242+ and wheel ["platform" ] == sys .platform ,
243+ base_wheel_bundles ,
244+ ),
245+ )
208246 )
209- )
210- assert len (zip_names_for_current_system ) == 1
211- zip_name = zip_names_for_current_system .pop ()
247+ assert len (zip_names_for_current_system ) == 1
248+ zip_name = zip_names_for_current_system .pop ()
212249 ensure_driver_bundle (zip_name )
213- zip_file = f"driver/playwright- { driver_version } - { zip_name } .zip"
250+ zip_file = driver_bundle_path ( zip_name )
214251 if os .path .exists ("playwright/driver" ):
215252 shutil .rmtree ("playwright/driver" )
216253 with zipfile .ZipFile (zip_file , "r" ) as zip :
217254 extractall (zip , "playwright/driver" )
218255
219256
220257setup (
221- cmdclass = {"bdist_wheel" : PlaywrightBDistWheelCommand },
258+ cmdclass = {
259+ "sdist" : PlaywrightSDistCommand ,
260+ "bdist_wheel" : PlaywrightBDistWheelCommand ,
261+ },
222262)
0 commit comments