Skip to content

Commit b9b90ee

Browse files
authored
Merge pull request #586 from stan-dev/fix/585-install-location
Fix location setting after install_cmdstan()
2 parents 3fe0469 + 2d7f280 commit b9b90ee

File tree

4 files changed

+38
-32
lines changed

4 files changed

+38
-32
lines changed

.github/workflows/main.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,14 @@ jobs:
9696
run: |
9797
install_cmdstan -h
9898
install_cxx_toolchain -h
99-
python -m cmdstanpy.install_cmdstan --version ${{ needs.get-cmdstan-version.outputs.version }}
99+
python -c "import cmdstanpy; cmdstanpy.install_cmdstan(version='${{ needs.get-cmdstan-version.outputs.version }}', cores=2)"
100100
101101
- name: Install CmdStan (Windows)
102102
if: matrix.os == 'windows-latest'
103103
run: |
104104
install_cmdstan -h
105105
install_cxx_toolchain -h
106-
python -m cmdstanpy.install_cmdstan --compiler --version ${{ needs.get-cmdstan-version.outputs.version }}
106+
python -m cmdstanpy.install_cmdstan --compiler --version ${{ needs.get-cmdstan-version.outputs.version }} --cores 2
107107
108108
- name: Run tests
109109
run: |

cmdstanpy/install_cmdstan.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@
77
example model ``bernoulli.stan``.
88
99
Optional command line arguments:
10+
-i, --interactive: flag, when specified ignore other arguments and
11+
ask user for settings on STDIN
1012
-v, --version <release> : version, defaults to latest release version
1113
-d, --dir <path> : install directory, defaults to '$HOME/.cmdstan
1214
--overwrite: flag, when specified re-installs existing version
1315
--progress: flag, when specified show progress bar for CmdStan download
1416
--verbose: flag, when specified prints output from CmdStan build process
17+
--cores: int, number of cores to use when building, defaults to 1
1518
-c, --compiler : flag, add C++ compiler to path (Windows only)
1619
"""
1720
import argparse

cmdstanpy/utils.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ def validate_cmdstan_path(path: str) -> None:
153153
raise ValueError(f'No CmdStan directory, path {path} does not exist.')
154154
if not os.path.exists(os.path.join(path, 'bin', 'stanc' + EXTENSION)):
155155
raise ValueError(
156-
'CmdStan installataion missing binaries. '
156+
f'CmdStan installataion missing binaries in {path}/bin. '
157157
'Re-install cmdstan by running command "install_cmdstan '
158158
'--overwrite", or Python code "import cmdstanpy; '
159159
'cmdstanpy.install_cmdstan(overwrite=True)"'
@@ -213,8 +213,9 @@ def cmdstan_version() -> Optional[Tuple[int, ...]]:
213213
"""
214214
try:
215215
makefile = os.path.join(cmdstan_path(), 'makefile')
216-
except ValueError:
216+
except ValueError as e:
217217
get_logger().info('No CmdStan installation found.')
218+
get_logger().debug("%s", e)
218219
return None
219220

220221
if not os.path.exists(makefile):
@@ -299,7 +300,7 @@ def cxx_toolchain_path(
299300
if os.path.exists(os.path.join(toolchain_root, 'mingw64')):
300301
compiler_path = os.path.join(
301302
toolchain_root,
302-
'mingw64' if (sys.maxsize > 2**32) else 'mingw32',
303+
'mingw64' if (sys.maxsize > 2 ** 32) else 'mingw32',
303304
'bin',
304305
)
305306
if os.path.exists(compiler_path):
@@ -323,7 +324,7 @@ def cxx_toolchain_path(
323324
elif os.path.exists(os.path.join(toolchain_root, 'mingw_64')):
324325
compiler_path = os.path.join(
325326
toolchain_root,
326-
'mingw_64' if (sys.maxsize > 2**32) else 'mingw_32',
327+
'mingw_64' if (sys.maxsize > 2 ** 32) else 'mingw_32',
327328
'bin',
328329
)
329330
if os.path.exists(compiler_path):
@@ -375,7 +376,7 @@ def cxx_toolchain_path(
375376
if version not in ('35', '3.5', '3'):
376377
compiler_path = os.path.join(
377378
toolchain_root,
378-
'mingw64' if (sys.maxsize > 2**32) else 'mingw32',
379+
'mingw64' if (sys.maxsize > 2 ** 32) else 'mingw32',
379380
'bin',
380381
)
381382
if os.path.exists(compiler_path):
@@ -400,7 +401,7 @@ def cxx_toolchain_path(
400401
else:
401402
compiler_path = os.path.join(
402403
toolchain_root,
403-
'mingw_64' if (sys.maxsize > 2**32) else 'mingw_32',
404+
'mingw_64' if (sys.maxsize > 2 ** 32) else 'mingw_32',
404405
'bin',
405406
)
406407
if os.path.exists(compiler_path):
@@ -1361,7 +1362,7 @@ def install_cmdstan(
13611362
logger.warning('CmdStan installation failed.\n%s', str(e))
13621363
return False
13631364

1364-
set_cmdstan_path(args.dir)
1365+
set_cmdstan_path(os.path.join(args.dir, f"cmdstan-{args.version}"))
13651366

13661367
return True
13671368

test/test_utils.py

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
import json
77
import logging
88
import os
9+
import pathlib
910
import platform
1011
import random
1112
import shutil
1213
import stat
1314
import string
1415
import tempfile
1516
import unittest
16-
from pathlib import Path
1717
from test import CustomTestCase
1818

1919
import numpy as np
@@ -137,18 +137,21 @@ def test_validate_path(self):
137137
path_foo = os.path.abspath(os.path.join('releases', 'foo'))
138138
with self.assertRaisesRegex(ValueError, 'No CmdStan directory'):
139139
validate_cmdstan_path(path_foo)
140+
140141
folder_name = ''.join(
141142
random.choice(string.ascii_letters) for _ in range(10)
142143
)
143144
while os.path.exists(folder_name):
144145
folder_name = ''.join(
145146
random.choice(string.ascii_letters) for _ in range(10)
146147
)
147-
os.makedirs(folder_name)
148-
path_test = os.path.abspath(folder_name)
148+
folder = pathlib.Path(folder_name)
149+
folder.mkdir(parents=True)
150+
(folder / "makefile").touch()
151+
149152
with self.assertRaisesRegex(ValueError, 'missing binaries'):
150-
validate_cmdstan_path(path_test)
151-
shutil.rmtree(folder_name)
153+
validate_cmdstan_path(str(folder.absolute()))
154+
shutil.rmtree(folder)
152155

153156
def test_validate_dir(self):
154157
with tempfile.TemporaryDirectory(
@@ -193,32 +196,31 @@ def test_cmdstan_version(self):
193196
with tempfile.TemporaryDirectory(
194197
prefix="cmdstan_tests", dir=_TMPDIR
195198
) as tmpdir:
196-
tdir = os.path.join(tmpdir, 'tmpdir_xxx')
197-
os.makedirs(tdir)
198-
fake_path = os.path.join(tdir, 'cmdstan-2.22.0')
199-
os.makedirs(os.path.join(fake_path))
200-
fake_bin = os.path.join(fake_path, 'bin')
201-
os.makedirs(fake_bin)
202-
Path(os.path.join(fake_bin, 'stanc' + EXTENSION)).touch()
203-
with self.modified_environ(CMDSTAN=fake_path):
204-
self.assertTrue(fake_path == cmdstan_path())
199+
tdir = pathlib.Path(tmpdir) / 'tmpdir_xxx'
200+
fake_path = tdir / 'cmdstan-2.22.0'
201+
fake_bin = fake_path / 'bin'
202+
fake_bin.mkdir(parents=True)
203+
fake_makefile = fake_path / 'makefile'
204+
fake_makefile.touch()
205+
(fake_bin / f'stanc{EXTENSION}').touch()
206+
with self.modified_environ(CMDSTAN=str(fake_path)):
207+
self.assertTrue(str(fake_path) == cmdstan_path())
208+
with open(fake_makefile, 'w') as fd:
209+
fd.write('... CMDSTAN_VERSION := dont_need_no_mmp\n\n')
205210
expect = (
206-
'CmdStan installation {} missing makefile, '
207-
'cannot get version.'.format(fake_path)
211+
'Cannot parse version, expected "<major>.<minor>.<patch>", '
212+
'found: "dont_need_no_mmp".'
208213
)
209214
with LogCapture() as log:
210-
logging.getLogger()
211215
cmdstan_version()
212216
log.check_present(('cmdstanpy', 'INFO', expect))
213-
fake_makefile = os.path.join(fake_path, 'makefile')
214-
with open(fake_makefile, 'w') as fd:
215-
fd.write('... CMDSTAN_VERSION := dont_need_no_mmp\n\n')
217+
218+
fake_makefile.unlink()
216219
expect = (
217-
'Cannot parse version, expected "<major>.<minor>.<patch>", '
218-
'found: "dont_need_no_mmp".'
220+
'CmdStan installation {} missing makefile, '
221+
'cannot get version.'.format(fake_path)
219222
)
220223
with LogCapture() as log:
221-
logging.getLogger()
222224
cmdstan_version()
223225
log.check_present(('cmdstanpy', 'INFO', expect))
224226
cmdstan_path()

0 commit comments

Comments
 (0)