Skip to content

Commit d371023

Browse files
committed
Add py.typed, also accept os.pathlike objects for paths
1 parent 39ee446 commit d371023

File tree

7 files changed

+38
-25
lines changed

7 files changed

+38
-25
lines changed

MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33

44
include requirements*.txt
55
include LICENSE.md
6+
include cmdstanpy/py.typed

cmdstanpy/cmdstan_args.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
write_stan_json,
2020
)
2121

22+
OptionalPath = Union[str, os.PathLike, None]
23+
2224

2325
class Method(Enum):
2426
"""Supported CmdStan method names."""
@@ -704,15 +706,15 @@ class CmdStanArgs:
704706
def __init__(
705707
self,
706708
model_name: str,
707-
model_exe: Optional[str],
709+
model_exe: OptionalPath,
708710
chain_ids: Optional[List[int]],
709711
method_args: Union[
710712
SamplerArgs, OptimizeArgs, GenerateQuantitiesArgs, VariationalArgs
711713
],
712714
data: Union[Mapping[str, Any], str, None] = None,
713715
seed: Union[int, List[int], None] = None,
714716
inits: Union[int, float, str, List[str], None] = None,
715-
output_dir: Optional[str] = None,
717+
output_dir: OptionalPath = None,
716718
sig_figs: Optional[int] = None,
717719
save_latent_dynamics: bool = False,
718720
save_profile: bool = False,

cmdstanpy/compiler_opts.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@
4848
'version',
4949
]
5050

51+
OptionalPath = Union[str, os.PathLike, None]
52+
5153

5254
class CompilerOptions:
5355
"""
@@ -64,12 +66,12 @@ def __init__(
6466
*,
6567
stanc_options: Optional[Dict[str, Any]] = None,
6668
cpp_options: Optional[Dict[str, Any]] = None,
67-
user_header: Optional[str] = None,
69+
user_header: OptionalPath = None,
6870
) -> None:
6971
"""Initialize object."""
7072
self._stanc_options = stanc_options if stanc_options is not None else {}
7173
self._cpp_options = cpp_options if cpp_options is not None else {}
72-
self._user_header = user_header if user_header is not None else ''
74+
self._user_header = str(user_header) if user_header is not None else ''
7375

7476
def __repr__(self) -> str:
7577
return 'stanc_options={}, cpp_options={}'.format(

cmdstanpy/model.py

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@
4949

5050
from . import progress as progbar
5151

52+
OptionalPath = Union[str, os.PathLike, None]
53+
5254

5355
class CmdStanModel:
5456
# overview, omitted from doc comment in order to improve Sphinx docs.
@@ -91,13 +93,13 @@ class CmdStanModel:
9193
def __init__(
9294
self,
9395
model_name: Optional[str] = None,
94-
stan_file: Optional[str] = None,
95-
exe_file: Optional[str] = None,
96+
stan_file: OptionalPath = None,
97+
exe_file: OptionalPath = None,
9698
# TODO should be Literal['force'] not str
9799
compile: Union[bool, str] = True,
98100
stanc_options: Optional[Dict[str, Any]] = None,
99101
cpp_options: Optional[Dict[str, Any]] = None,
100-
user_header: Optional[str] = None,
102+
user_header: OptionalPath = None,
101103
) -> None:
102104
"""
103105
Initialize object given constructor args.
@@ -232,12 +234,12 @@ def name(self) -> str:
232234
return self._name
233235

234236
@property
235-
def stan_file(self) -> Optional[str]:
237+
def stan_file(self) -> OptionalPath:
236238
"""Full path to Stan program file."""
237239
return self._stan_file
238240

239241
@property
240-
def exe_file(self) -> Optional[str]:
242+
def exe_file(self) -> OptionalPath:
241243
"""Full path to Stan exe file."""
242244
return self._exe_file
243245

@@ -253,7 +255,7 @@ def exe_info(self) -> Dict[str, str]:
253255
return result
254256
try:
255257
info = StringIO()
256-
do_command(cmd=[self.exe_file, 'info'], fd_out=info)
258+
do_command(cmd=[str(self.exe_file), 'info'], fd_out=info)
257259
lines = info.getvalue().split('\n')
258260
for line in lines:
259261
kv_pair = [x.strip() for x in line.split('=')]
@@ -282,7 +284,7 @@ def src_info(self) -> Dict[str, Any]:
282284
+ self._compiler_options.compose_stanc()
283285
+ [
284286
'--info',
285-
self.stan_file,
287+
str(self.stan_file),
286288
]
287289
)
288290
proc = subprocess.run(
@@ -331,7 +333,7 @@ def format(
331333
[os.path.join(cmdstan_path(), 'bin', 'stanc' + EXTENSION)]
332334
# handle include-paths, allow-undefined etc
333335
+ self._compiler_options.compose_stanc()
334-
+ [self.stan_file]
336+
+ [str(self.stan_file)]
335337
)
336338

337339
if canonicalize:
@@ -379,7 +381,7 @@ def format(
379381
if backup:
380382
shutil.copyfile(
381383
self.stan_file,
382-
self.stan_file
384+
str(self.stan_file)
383385
+ '.bak-'
384386
+ datetime.now().strftime("%Y%m%d%H%M%S"),
385387
)
@@ -426,7 +428,7 @@ def compile(
426428
force: bool = False,
427429
stanc_options: Optional[Dict[str, Any]] = None,
428430
cpp_options: Optional[Dict[str, Any]] = None,
429-
user_header: Optional[str] = None,
431+
user_header: OptionalPath = None,
430432
override_options: bool = False,
431433
) -> None:
432434
"""
@@ -569,10 +571,10 @@ def compile(
569571

570572
def optimize(
571573
self,
572-
data: Union[Mapping[str, Any], str, None] = None,
574+
data: Union[Mapping[str, Any], str, os.PathLike, None] = None,
573575
seed: Optional[int] = None,
574-
inits: Union[Dict[str, float], float, str, None] = None,
575-
output_dir: Optional[str] = None,
576+
inits: Union[Dict[str, float], float, str, os.PathLike, None] = None,
577+
output_dir: OptionalPath = None,
576578
sig_figs: Optional[int] = None,
577579
save_profile: bool = False,
578580
algorithm: Optional[str] = None,
@@ -733,7 +735,7 @@ def optimize(
733735
# pylint: disable=too-many-arguments
734736
def sample(
735737
self,
736-
data: Union[Mapping[str, Any], str, None] = None,
738+
data: Union[Mapping[str, Any], str, os.PathLike, None] = None,
737739
chains: Optional[int] = None,
738740
parallel_chains: Optional[int] = None,
739741
threads_per_chain: Optional[int] = None,
@@ -755,7 +757,7 @@ def sample(
755757
adapt_metric_window: Optional[int] = None,
756758
adapt_step_size: Optional[int] = None,
757759
fixed_param: bool = False,
758-
output_dir: Optional[str] = None,
760+
output_dir: OptionalPath = None,
759761
sig_figs: Optional[int] = None,
760762
save_latent_dynamics: bool = False,
761763
save_profile: bool = False,
@@ -1197,10 +1199,10 @@ def sample(
11971199

11981200
def generate_quantities(
11991201
self,
1200-
data: Union[Mapping[str, Any], str, None] = None,
1202+
data: Union[Mapping[str, Any], str, os.PathLike, None] = None,
12011203
mcmc_sample: Union[CmdStanMCMC, List[str], None] = None,
12021204
seed: Optional[int] = None,
1203-
gq_output_dir: Optional[str] = None,
1205+
gq_output_dir: OptionalPath = None,
12041206
sig_figs: Optional[int] = None,
12051207
show_console: bool = False,
12061208
refresh: Optional[int] = None,
@@ -1341,10 +1343,10 @@ def generate_quantities(
13411343

13421344
def variational(
13431345
self,
1344-
data: Union[Mapping[str, Any], str, None] = None,
1346+
data: Union[Mapping[str, Any], str, os.PathLike, None] = None,
13451347
seed: Optional[int] = None,
13461348
inits: Optional[float] = None,
1347-
output_dir: Optional[str] = None,
1349+
output_dir: OptionalPath = None,
13481350
sig_figs: Optional[int] = None,
13491351
save_latent_dynamics: bool = False,
13501352
save_profile: bool = False,

cmdstanpy/py.typed

Whitespace-only changes.

cmdstanpy/utils.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1381,7 +1381,9 @@ class MaybeDictToFilePath:
13811381

13821382
def __init__(
13831383
self,
1384-
*objs: Union[str, Mapping[str, Any], List[Any], int, float, None],
1384+
*objs: Union[
1385+
str, Mapping[str, Any], List[Any], int, float, os.PathLike, None
1386+
],
13851387
):
13861388
self._unlink = [False] * len(objs)
13871389
self._paths: List[Any] = [''] * len(objs)
@@ -1396,7 +1398,7 @@ def __init__(
13961398
write_stan_json(data_file, obj)
13971399
self._paths[i] = data_file
13981400
self._unlink[i] = True
1399-
elif isinstance(obj, str):
1401+
elif isinstance(obj, (str, os.PathLike)):
14001402
if not os.path.exists(obj):
14011403
raise ValueError("File doesn't exist {}".format(obj))
14021404
self._paths[i] = obj

setup.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,11 @@ def get_version() -> str:
7272
long_description_content_type="text/markdown",
7373
author='Stan Dev Team',
7474
url='https://github.com/stan-dev/cmdstanpy',
75+
license_files=['LICENSE.md'],
7576
packages=['cmdstanpy', 'cmdstanpy.stanfit'],
77+
package_data={
78+
'cmdstanpy': ['py.typed'],
79+
},
7680
entry_points={
7781
'console_scripts': [
7882
'install_cmdstan=cmdstanpy.install_cmdstan:__main__',

0 commit comments

Comments
 (0)