stepss 3.59__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
stepss/globals.py ADDED
@@ -0,0 +1,154 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ """Global module variables and utilities shared across stepss.
4
+
5
+ Provides:
6
+ - Module-level configuration flags (``__runTimeObs__``) and the resolved
7
+ paths to the bundled native libraries: ``__libdir__`` (the ``libs/`` root,
8
+ holding the platform-independent C headers) and ``__platlibdir__`` (the
9
+ platform subdirectory ``libs/win``, ``libs/lin`` or ``libs/mac`` holding
10
+ the shared libraries for the current platform).
11
+ - ``RAMSESError`` — custom exception for RAMSES solver failures.
12
+ - Helper functions used by :mod:`stepss.cases` and :mod:`stepss.simulator`.
13
+ """
14
+
15
+ import errno
16
+ import inspect
17
+ import os
18
+ import sys
19
+
20
+ __runTimeObs__ = True
21
+ __libdir__ = os.path.realpath(
22
+ os.path.abspath(os.path.join(os.path.split(inspect.getfile(inspect.currentframe()))[0], "libs")))
23
+
24
+
25
+ def _platform_subdir():
26
+ """Return the ``libs/`` subdirectory name for the current platform.
27
+
28
+ The macOS and Linux RAMSES builds share the filename ``ramses.so``, so
29
+ the bundled libraries are kept in per-platform subdirectories:
30
+ ``win`` (Windows), ``mac`` (macOS), ``lin`` (Linux and everything else).
31
+
32
+ :returns: platform folder name, one of ``'win'``, ``'mac'``, ``'lin'``
33
+ :rtype: str
34
+ """
35
+ if sys.platform in ('win32', 'cygwin'):
36
+ return 'win'
37
+ if sys.platform == 'darwin':
38
+ return 'mac'
39
+ return 'lin'
40
+
41
+
42
+ __platlibdir__ = os.path.join(__libdir__, _platform_subdir())
43
+
44
+
45
+ def CustomWarning(message, category, filename, lineno, file=None, line=None):
46
+ """Format and print a RAMSES warning to stdout.
47
+
48
+ Replaces the default :func:`warnings.showwarning` handler so that all
49
+ warnings issued by stepss carry the ``RAMSESWarning:`` prefix.
50
+
51
+ :param message: warning message object
52
+ :param category: warning category class (unused; included for API compatibility)
53
+ :param filename: source file that triggered the warning (unused; included for API compatibility)
54
+ :param lineno: line number that triggered the warning (unused; included for API compatibility)
55
+ :param file: output file object (unused; always writes to stdout)
56
+ :param line: source line text (unused; included for API compatibility)
57
+
58
+ .. note:: This function writes directly to stdout and has no return value.
59
+ """
60
+ print("RAMSESWarning: %s" % message)
61
+
62
+
63
+ def read_file(fname):
64
+ """Read and return the text content of a file bundled with the package.
65
+
66
+ The path is resolved relative to the directory containing this module,
67
+ making it suitable for reading package data files (e.g. ``README.rst``).
68
+
69
+ :param str fname: filename relative to the stepss package directory
70
+ :returns: full text content of the file
71
+ :rtype: str
72
+ :raises IOError: if the file cannot be opened
73
+ """
74
+ with open(os.path.join(os.path.dirname(__file__), fname)) as f:
75
+ return f.read()
76
+
77
+
78
+ class RAMSESError(Exception):
79
+ """Exception raised for errors returned by the RAMSES solver.
80
+
81
+ Raised when a RAMSES C library call returns a non-zero status code that
82
+ cannot be recovered from, or when arguments supplied to a stepss function
83
+ are inconsistent with the current solver state.
84
+ """
85
+ pass
86
+
87
+
88
+ class HeliosError(Exception):
89
+ """Exception raised for errors returned by the Helios power-flow engine.
90
+
91
+ Raised when a helios C library call returns a negative status code; the
92
+ message includes the diagnostic text retrieved from the library's
93
+ per-handle error channel (``helios_get_last_error``).
94
+ """
95
+ pass
96
+
97
+
98
+ def __which(program):
99
+ """Locate a program on the system PATH, similar to the Unix ``which`` command.
100
+
101
+ :param str program: executable name (with or without full path)
102
+ :returns: full path to the executable if found and executable, otherwise ``None``
103
+ :rtype: str or None
104
+ """
105
+
106
+ def is_exe(fpath):
107
+ """Return True if *fpath* is a regular file and is executable."""
108
+ return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
109
+
110
+ fpath, fname = os.path.split(program)
111
+ if fpath:
112
+ if is_exe(program):
113
+ return program
114
+ else:
115
+ for path in os.environ.get("PATH", "").split(os.pathsep):
116
+ path = path.strip('"')
117
+ exe_file = os.path.join(path, program)
118
+ if is_exe(exe_file):
119
+ return exe_file
120
+
121
+ return None
122
+
123
+
124
+ def silentremove(filename):
125
+ """Delete a file, silently ignoring the case where it does not exist.
126
+
127
+ Any other OS-level error (e.g. permission denied) is re-raised unchanged.
128
+
129
+ :param str filename: path of the file to remove
130
+ :raises OSError: if deletion fails for any reason other than the file not existing
131
+ """
132
+
133
+ try:
134
+ os.remove(filename)
135
+ except OSError as e:
136
+ if e.errno != errno.ENOENT: # errno.ENOENT = no such file or directory
137
+ raise # re-raise exception if a different error occured
138
+
139
+ def wrapToList(item):
140
+ """Wrap *item* in a list if it is not already a list.
141
+
142
+ Used to normalise arguments that may be passed as a single scalar or as a
143
+ list, so that the rest of the calling code can always iterate uniformly.
144
+
145
+ :param item: value to wrap
146
+ :returns: *item* unchanged if it is already a list, otherwise ``[item]``
147
+ :rtype: list
148
+ """
149
+ if not isinstance(item, list):
150
+ return [item]
151
+ else:
152
+ return item
153
+
154
+