Skip to content

Commit a46dcf2

Browse files
committed
removing openw class
1 parent 401a386 commit a46dcf2

File tree

1 file changed

+73
-119
lines changed

1 file changed

+73
-119
lines changed

setup.py

Lines changed: 73 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@
88

99
import argparse
1010
import glob
11-
import io as cStringIO
1211
import os
13-
import pathlib
1412
import re
1513
import shutil
1614
import sys
1715
import sysconfig
1816
import time
1917
from collections import defaultdict
18+
from itertools import chain
19+
from pathlib import Path
2020
from subprocess import PIPE, Popen
2121

2222
import numpy
@@ -26,97 +26,63 @@
2626
from setuptools.command.install import install
2727

2828
# non-empty DEBUG variable turns off optimization and adds -g flag
29-
DEBUG = bool(os.getenv("DEBUG", ""))
29+
DEBUG = bool(os.getenv("DEBUG", False))
3030
WIN = sys.platform.startswith("win")
3131
MAC = sys.platform.startswith("darwin")
3232

3333

3434
# Have to copy from "create_shadertext.py" script due to the use of pyproject.toml
3535
# Full explanation:
3636
# https://github.com/pypa/setuptools/issues/3939
37-
def create_all(generated_dir, pymoldir="."):
37+
def create_all(generated_dir: str, pymol_dir: str = "."):
3838
"""
3939
Generate various stuff
4040
"""
41-
create_shadertext(
42-
os.path.join(pymoldir, "data", "shaders"),
43-
generated_dir,
44-
os.path.join(generated_dir, "ShaderText.h"),
45-
os.path.join(generated_dir, "ShaderText.cpp"),
46-
)
47-
create_buildinfo(generated_dir, pymoldir)
48-
49-
50-
class openw(object):
51-
"""
52-
File-like object for writing files. File is actually only
53-
written if the content changed.
54-
"""
55-
56-
def __init__(self, filename):
57-
if os.path.exists(filename):
58-
self.out = cStringIO.StringIO()
59-
self.filename = filename
60-
else:
61-
os.makedirs(os.path.dirname(filename), exist_ok=True)
62-
self.out = open(filename, "w")
63-
self.filename = None
41+
generated_dir_path = Path(generated_dir)
42+
pymol_dir_path = Path(pymol_dir)
6443

65-
def close(self):
66-
if self.out.closed:
67-
return
68-
if self.filename:
69-
with open(self.filename) as handle:
70-
oldcontents = handle.read()
71-
newcontents = self.out.getvalue()
72-
if oldcontents != newcontents:
73-
self.out = open(self.filename, "w")
74-
self.out.write(newcontents)
75-
self.out.close()
76-
77-
def __getattr__(self, name):
78-
return getattr(self.out, name)
79-
80-
def __enter__(self):
81-
return self
82-
83-
def __exit__(self, *a, **k):
84-
self.close()
85-
86-
def __del__(self):
87-
self.close()
44+
generated_dir_path.mkdir(parents=True, exist_ok=True)
45+
pymol_dir_path.mkdir(parents=True, exist_ok=True)
8846

47+
create_shadertext(
48+
shader_dir=generated_dir_path / "data" / "shaders",
49+
shader_dir2=pymol_dir_path,
50+
output_header=generated_dir_path / "ShaderText.h",
51+
output_source=generated_dir_path / "ShaderText.cpp",
52+
)
53+
create_buildinfo(generated_dir, pymol_dir)
8954

90-
def create_shadertext(shaderdir, shaderdir2, outputheader, outputfile):
91-
outputheader = openw(outputheader)
92-
outputfile = openw(outputfile)
9355

56+
def create_shadertext(
57+
shader_dir: Path,
58+
shader_dir2: Path,
59+
output_header: Path,
60+
output_source: Path,
61+
):
62+
varname = "_shader_cache_raw"
9463
include_deps = defaultdict(set)
9564
ifdef_deps = defaultdict(set)
65+
extension_regexp = "*.[gs][vs][fs][shared][tsc][tse]"
9666

9767
# get all *.gs *.vs *.fs *.shared from the two input directories
98-
shaderfiles = set()
99-
for sdir in [shaderdir, shaderdir2]:
100-
for ext in ["gs", "vs", "fs", "shared", "tsc", "tse"]:
101-
shaderfiles.update(
102-
map(os.path.basename, sorted(glob.glob(os.path.join(sdir, "*." + ext))))
103-
)
104-
105-
varname = "_shader_cache_raw"
106-
outputheader.write("extern const char * %s[];\n" % varname)
107-
outputfile.write("const char * %s[] = {\n" % varname)
108-
109-
for filename in sorted(shaderfiles):
110-
shaderfile = os.path.join(shaderdir, filename)
111-
if not os.path.exists(shaderfile):
112-
shaderfile = os.path.join(shaderdir2, filename)
68+
shaderfiles = set(
69+
chain(
70+
shader_dir.glob(extension_regexp),
71+
shader_dir2.glob(extension_regexp),
72+
)
73+
)
11374

114-
with open(shaderfile, "r") as handle:
115-
contents = handle.read()
75+
with (
76+
open(output_header, "w") as output_header_file,
77+
open(output_source, "w") as output_source_file,
78+
):
79+
output_header_file.write(f"extern const char * {varname}[];\n")
80+
output_source_file.write(f"const char * {varname}[] = {{\n")
11681

117-
if True:
118-
outputfile.write('"%s", ""\n' % (filename))
82+
for filename in shaderfiles:
83+
output_source_file.write(f'"{filename.name}", ""\n')
11984

85+
contents = filename.read_text()
12086
for line in contents.splitlines():
12187
line = line.strip()
12288

@@ -125,52 +91,43 @@ def create_shadertext(shaderdir, shaderdir2, outputheader, outputfile):
12591
continue
12692

12793
# write line, quoted, escaped and with a line feed
128-
outputfile.write(
129-
'"%s\\n"\n' % line.replace("\\", "\\\\").replace('"', r"\"")
130-
)
94+
escaped_line = line.replace("\\", "\\\\").replace('"', r"\"")
95+
output_source_file.write(f'"{escaped_line}\\n"\n')
13196

13297
# include and ifdef dependencies
13398
if line.startswith("#include"):
13499
include_deps[line.split()[1]].add(filename)
135100
elif line.startswith("#ifdef") or line.startswith("#ifndef"):
136101
ifdef_deps[line.split()[1]].add(filename)
137102

138-
outputfile.write(",\n")
139-
140-
outputfile.write("0};\n")
141-
142-
# include and ifdef dependencies
143-
for varname, deps in [("_include_deps", include_deps), ("_ifdef_deps", ifdef_deps)]:
144-
outputheader.write("extern const char * %s[];\n" % varname)
145-
outputfile.write("const char * %s[] = {\n" % varname)
146-
for name, itemdeps in deps.items():
147-
outputfile.write('"%s", "%s", 0,\n' % (name, '", "'.join(sorted(itemdeps))))
148-
outputfile.write("0};\n")
103+
output_source_file.write(",\n")
104+
output_source_file.write("0};\n")
149105

150-
outputheader.close()
151-
outputfile.close()
152-
153-
154-
def create_buildinfo(outputdir, pymoldir="."):
155-
try:
156-
sha = (
157-
Popen(["git", "rev-parse", "HEAD"], cwd=pymoldir, stdout=PIPE)
158-
.stdout.read()
159-
.strip()
160-
.decode()
161-
)
162-
except OSError:
163-
sha = ""
164-
165-
with openw(os.path.join(outputdir, "PyMOLBuildInfo.h")) as out:
166-
print(
167-
"""
168-
#define _PyMOL_BUILD_DATE %d
169-
#define _PYMOL_BUILD_GIT_SHA "%s"
170-
"""
171-
% (time.time(), sha),
172-
file=out,
173-
)
106+
# include and ifdef dependencies
107+
for varname, deps in [
108+
("_include_deps", include_deps),
109+
("_ifdef_deps", ifdef_deps),
110+
]:
111+
output_header_file.write(f"extern const char * {varname}[];\n")
112+
output_source_file.write(f"const char * {varname}[] = {{\n")
113+
for name, item_deps in deps.items():
114+
item_deps = '", "'.join(sorted(item_deps))
115+
output_source_file.write(f'"{name}", "{item_deps}", 0,\n')
116+
output_source_file.write("0};\n")
117+
118+
119+
def create_buildinfo(output_dir_path: str, pymoldir: str = "."):
120+
output_dir = Path(output_dir_path)
121+
sha_raw = Popen(["git", "rev-parse", "HEAD"], cwd=pymoldir, stdout=PIPE).stdout
122+
sha = sha_raw.read().strip().decode() if sha_raw is not None else ""
123+
124+
info_file = output_dir / "PyMOLBuildInfo.h"
125+
info_file.write_text(
126+
f"""
127+
#define _PyMOL_BUILD_DATE {time.time()}
128+
#define _PYMOL_BUILD_GIT_SHA "{sha}"
129+
"""
130+
)
174131

175132

176133
# handle extra arguments
@@ -302,7 +259,6 @@ def guess_msgpackc():
302259

303260

304261
class CMakeExtension(Extension):
305-
306262
def __init__(
307263
self,
308264
name,
@@ -336,15 +292,15 @@ def run(self):
336292
self.build_cmake(ext)
337293

338294
def build_cmake(self, ext):
339-
cwd = pathlib.Path().absolute()
295+
cwd = Path().absolute()
340296

341297
# these dirs will be created in build_py, so if you don't have
342298
# any python sources to bundle, the dirs will be missing
343299
name_split = ext.name.split(".")
344300
target_name = name_split[-1]
345-
build_temp = pathlib.Path(self.build_temp) / target_name
301+
build_temp = Path(self.build_temp) / target_name
346302
build_temp.mkdir(parents=True, exist_ok=True)
347-
extdir = pathlib.Path(self.get_ext_fullpath(ext.name))
303+
extdir = Path(self.get_ext_fullpath(ext.name))
348304
extdirabs = extdir.absolute()
349305

350306
extdir.parent.mkdir(parents=True, exist_ok=True)
@@ -394,7 +350,7 @@ def concat_paths(paths):
394350

395351
if WIN:
396352
# Move up from VS release folder
397-
cmake_lib_loc = pathlib.Path(
353+
cmake_lib_loc = Path(
398354
lib_output_dir, "Release", f"{target_name}{shared_suffix}"
399355
)
400356
if cmake_lib_loc.exists():
@@ -487,7 +443,7 @@ def make_launch_script(self):
487443
launch_script = os.path.join(self.install_scripts, launch_script)
488444

489445
python_exe = os.path.abspath(sys.executable)
490-
site_packages_dir = sysconfig.get_path('purelib')
446+
site_packages_dir = sysconfig.get_path("purelib")
491447
pymol_file = self.unchroot(
492448
os.path.join(site_packages_dir, "pymol", "__init__.py")
493449
)
@@ -701,8 +657,6 @@ def make_launch_script(self):
701657
libs += [
702658
"opengl32",
703659
]
704-
# TODO: Remove when we move to setup-CMake
705-
ext_comp_args += ["/std:c++17"]
706660

707661
if not (MAC or WIN):
708662
libs += [
@@ -816,7 +770,7 @@ def get_packages(base, parent="", r=None):
816770

817771
if WIN:
818772
# pyconfig.py forces linking against pythonXY.lib on MSVC
819-
py_lib = pathlib.Path(sysconfig.get_paths()["stdlib"]).parent / "libs"
773+
py_lib = Path(sysconfig.get_paths()["stdlib"]).parent / "libs"
820774
lib_dirs.append(str(py_lib))
821775

822776
ext_modules += [

0 commit comments

Comments
 (0)