omdev 0.0.0.dev7__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.
Files changed (67) hide show
  1. omdev/__about__.py +35 -0
  2. omdev/__init__.py +0 -0
  3. omdev/amalg/__init__.py +0 -0
  4. omdev/amalg/__main__.py +4 -0
  5. omdev/amalg/amalg.py +513 -0
  6. omdev/classdot.py +61 -0
  7. omdev/cmake.py +164 -0
  8. omdev/exts/__init__.py +0 -0
  9. omdev/exts/_distutils/__init__.py +10 -0
  10. omdev/exts/_distutils/build_ext.py +367 -0
  11. omdev/exts/_distutils/compilers/__init__.py +3 -0
  12. omdev/exts/_distutils/compilers/ccompiler.py +1032 -0
  13. omdev/exts/_distutils/compilers/options.py +80 -0
  14. omdev/exts/_distutils/compilers/unixccompiler.py +385 -0
  15. omdev/exts/_distutils/dir_util.py +76 -0
  16. omdev/exts/_distutils/errors.py +62 -0
  17. omdev/exts/_distutils/extension.py +107 -0
  18. omdev/exts/_distutils/file_util.py +216 -0
  19. omdev/exts/_distutils/modified.py +47 -0
  20. omdev/exts/_distutils/spawn.py +103 -0
  21. omdev/exts/_distutils/sysconfig.py +349 -0
  22. omdev/exts/_distutils/util.py +201 -0
  23. omdev/exts/_distutils/version.py +308 -0
  24. omdev/exts/build.py +43 -0
  25. omdev/exts/cmake.py +195 -0
  26. omdev/exts/importhook.py +88 -0
  27. omdev/exts/scan.py +74 -0
  28. omdev/interp/__init__.py +1 -0
  29. omdev/interp/__main__.py +4 -0
  30. omdev/interp/cli.py +63 -0
  31. omdev/interp/inspect.py +105 -0
  32. omdev/interp/providers.py +67 -0
  33. omdev/interp/pyenv.py +353 -0
  34. omdev/interp/resolvers.py +76 -0
  35. omdev/interp/standalone.py +187 -0
  36. omdev/interp/system.py +125 -0
  37. omdev/interp/types.py +92 -0
  38. omdev/mypy/__init__.py +0 -0
  39. omdev/mypy/debug.py +86 -0
  40. omdev/pyproject/__init__.py +1 -0
  41. omdev/pyproject/__main__.py +4 -0
  42. omdev/pyproject/cli.py +319 -0
  43. omdev/pyproject/configs.py +97 -0
  44. omdev/pyproject/ext.py +107 -0
  45. omdev/pyproject/pkg.py +196 -0
  46. omdev/scripts/__init__.py +0 -0
  47. omdev/scripts/execrss.py +19 -0
  48. omdev/scripts/findimports.py +62 -0
  49. omdev/scripts/findmagic.py +70 -0
  50. omdev/scripts/interp.py +2118 -0
  51. omdev/scripts/pyproject.py +3584 -0
  52. omdev/scripts/traceimport.py +502 -0
  53. omdev/tokens.py +42 -0
  54. omdev/toml/__init__.py +1 -0
  55. omdev/toml/parser.py +823 -0
  56. omdev/toml/writer.py +104 -0
  57. omdev/tools/__init__.py +0 -0
  58. omdev/tools/dockertools.py +81 -0
  59. omdev/tools/sqlrepl.py +193 -0
  60. omdev/versioning/__init__.py +1 -0
  61. omdev/versioning/specifiers.py +531 -0
  62. omdev/versioning/versions.py +416 -0
  63. omdev-0.0.0.dev7.dist-info/LICENSE +21 -0
  64. omdev-0.0.0.dev7.dist-info/METADATA +24 -0
  65. omdev-0.0.0.dev7.dist-info/RECORD +67 -0
  66. omdev-0.0.0.dev7.dist-info/WHEEL +5 -0
  67. omdev-0.0.0.dev7.dist-info/top_level.txt +1 -0
@@ -0,0 +1,107 @@
1
+ """Provides the Extension class, used to describe C/C++ extension modules in setup scripts."""
2
+ import warnings
3
+
4
+
5
+ class Extension:
6
+ """
7
+ Just a collection of attributes that describes an extension module and everything needed to build it (hopefully in a
8
+ portable way, but there are hooks that let you be as unportable as you need).
9
+
10
+ Instance attributes:
11
+ name : string
12
+ the full name of the extension, including any packages -- ie. *not* a filename or pathname, but Python dotted
13
+ name
14
+ sources : [string]
15
+ list of source filenames, relative to the distribution root (where the setup script lives), in Unix form
16
+ (slash-separated) for portability. Source files may be C, C++, SWIG (.i), platform-specific resource files, or
17
+ whatever else is recognized by the "build_ext" command as source for a Python extension.
18
+ include_dirs : [string]
19
+ list of directories to search for C/C++ header files (in Unix form for portability)
20
+ define_macros : [(name : string, value : string|None)]
21
+ list of macros to define; each macro is defined using a 2-tuple, where 'value' is either the string to define it
22
+ to or None to define it without a particular value (equivalent of "#define FOO" in source or -DFOO on Unix C
23
+ compiler command line)
24
+ undef_macros : [string]
25
+ list of macros to undefine explicitly
26
+ library_dirs : [string]
27
+ list of directories to search for C/C++ libraries at link time
28
+ libraries : [string]
29
+ list of library names (not filenames or paths) to link against
30
+ runtime_library_dirs : [string]
31
+ list of directories to search for C/C++ libraries at run time (for shared extensions, this is when the extension
32
+ is loaded)
33
+ extra_objects : [string]
34
+ list of extra files to link with (eg. object files not implied by 'sources', static library that must be
35
+ explicitly specified, binary resource files, etc.)
36
+ extra_compile_args : [string]
37
+ any extra platform- and compiler-specific information to use when compiling the source files in 'sources'. For
38
+ platforms and compilers where "command line" makes sense, this is typically a list of command-line arguments,
39
+ but for other platforms it could be anything.
40
+ extra_link_args : [string]
41
+ any extra platform- and compiler-specific information to use when linking object files together to create the
42
+ extension (or to create a new static Python interpreter). Similar interpretation as for 'extra_compile_args'.
43
+ export_symbols : [string]
44
+ list of symbols to be exported from a shared extension. Not used on all platforms, and not generally necessary
45
+ for Python extensions, which typically export exactly one symbol: "init" + extension_name.
46
+ swig_opts : [string]
47
+ any extra options to pass to SWIG if a source file has the .i extension.
48
+ depends : [string]
49
+ list of files that the extension depends on
50
+ language : string
51
+ extension language (i.e. "c", "c++", "objc"). Will be detected from the source extensions if not provided.
52
+ optional : boolean
53
+ specifies that a build failure in the extension should not abort the build process, but simply not install the
54
+ failing extension.
55
+ """
56
+
57
+ # When adding arguments to this constructor, be sure to update setup_keywords in core.py.
58
+ def __init__(
59
+ self,
60
+ name: str,
61
+ sources: list[str],
62
+ include_dirs: list[str] | None = None,
63
+ define_macros: list[tuple[str, str]] | None = None,
64
+ undef_macros: list[str] | None = None,
65
+ library_dirs: list[str] | None = None,
66
+ libraries: list[str] | None = None,
67
+ runtime_library_dirs: list[str] | None = None,
68
+ extra_objects: list[str] | None = None,
69
+ extra_compile_args: list[str] | None = None,
70
+ extra_link_args: list[str] | None = None,
71
+ export_symbols: list[str] | None = None,
72
+ swig_opts: list[str] | None = None,
73
+ depends: list[str] | None = None,
74
+ language: str | None = None,
75
+ optional: str | None = None,
76
+ **kw, # To catch unknown keywords
77
+ ):
78
+ if not isinstance(name, str):
79
+ raise TypeError("'name' must be a string")
80
+ if not (isinstance(sources, list) and all(isinstance(v, str) for v in sources)):
81
+ raise TypeError("'sources' must be a list of strings")
82
+
83
+ self.name = name
84
+ self.sources = sources
85
+ self.include_dirs = include_dirs or []
86
+ self.define_macros = define_macros or []
87
+ self.undef_macros = undef_macros or []
88
+ self.library_dirs = library_dirs or []
89
+ self.libraries = libraries or []
90
+ self.runtime_library_dirs = runtime_library_dirs or []
91
+ self.extra_objects = extra_objects or []
92
+ self.extra_compile_args = extra_compile_args or []
93
+ self.extra_link_args = extra_link_args or []
94
+ self.export_symbols = export_symbols or []
95
+ self.swig_opts = swig_opts or []
96
+ self.depends = depends or []
97
+ self.language = language
98
+ self.optional = optional
99
+
100
+ # If there are unknown keyword options, warn about them
101
+ if len(kw) > 0:
102
+ options = ', '.join(sorted([repr(option) for option in kw]))
103
+ msg = f'Unknown Extension options: {options}'
104
+ warnings.warn(msg)
105
+
106
+ def __repr__(self):
107
+ return f'<{self.__class__.__module__}.{self.__class__.__qualname__}({self.name!r}) at {id(self):#x}>'
@@ -0,0 +1,216 @@
1
+ """Utility functions for operating on single files."""
2
+ import contextlib
3
+ import logging
4
+ import os
5
+
6
+ from .errors import DistutilsFileError
7
+
8
+
9
+ log = logging.getLogger(__name__)
10
+
11
+
12
+ # for generating verbose output in 'copy_file()'
13
+ _copy_action = {None: 'copying', 'hard': 'hard linking', 'sym': 'symbolically linking'}
14
+
15
+
16
+ def _copy_file_contents(src, dst, buffer_size=16 * 1024): # noqa: C901
17
+ """
18
+ Copy the file 'src' to 'dst'; both must be filenames. Any error opening either file, reading from 'src', or writing
19
+ to 'dst', raises DistutilsFileError. Data is read/written in chunks of 'buffer_size' bytes (default 16k). No
20
+ attempt is made to handle anything apart from regular files.
21
+ """
22
+ # Stolen from shutil module in the standard library, but with custom error-handling added.
23
+ fsrc = None
24
+ fdst = None
25
+ try:
26
+ try:
27
+ fsrc = open(src, 'rb') # noqa
28
+ except OSError as e:
29
+ raise DistutilsFileError(f"could not open '{src}': {e.strerror}") from None
30
+
31
+ if os.path.exists(dst):
32
+ try:
33
+ os.unlink(dst)
34
+ except OSError as e:
35
+ raise DistutilsFileError(f"could not delete '{dst}': {e.strerror}") from None
36
+
37
+ try:
38
+ fdst = open(dst, 'wb') # noqa
39
+ except OSError as e:
40
+ raise DistutilsFileError(f"could not create '{dst}': {e.strerror}") from None
41
+
42
+ while True:
43
+ try:
44
+ buf = fsrc.read(buffer_size)
45
+ except OSError as e:
46
+ raise DistutilsFileError(f"could not read from '{src}': {e.strerror}") from None
47
+
48
+ if not buf:
49
+ break
50
+
51
+ try:
52
+ fdst.write(buf)
53
+ except OSError as e:
54
+ raise DistutilsFileError(f"could not write to '{dst}': {e.strerror}") from None
55
+
56
+ finally:
57
+ if fdst:
58
+ fdst.close()
59
+ if fsrc:
60
+ fsrc.close()
61
+
62
+
63
+ def copy_file( # noqa: C901
64
+ src,
65
+ dst,
66
+ preserve_mode=1,
67
+ preserve_times=1,
68
+ update=0,
69
+ link=None,
70
+ verbose=1,
71
+ dry_run=False,
72
+ ):
73
+ """
74
+ Copy a file 'src' to 'dst'. If 'dst' is a directory, then 'src' is copied there with the same name; otherwise, it
75
+ must be a filename. (If the file exists, it will be ruthlessly clobbered.) If 'preserve_mode' is true (the
76
+ default), the file's mode (type and permission bits, or whatever is analogous on the current platform) is copied.
77
+ If 'preserve_times' is true (the default), the last-modified and last-access times are copied as well. If 'update'
78
+ is true, 'src' will only be copied if 'dst' does not exist, or if 'dst' does exist but is older than 'src'.
79
+
80
+ 'link' allows you to make hard links (os.link) or symbolic links (os.symlink) instead of copying: set it to "hard"
81
+ or "sym"; if it is None (the default), files are copied. Don't set 'link' on systems that don't support it:
82
+ 'copy_file()' doesn't check if hard or symbolic linking is available. If hardlink fails, falls back to
83
+ _copy_file_contents().
84
+
85
+ Under Mac OS, uses the native file copy function in macostools; on other systems, uses '_copy_file_contents()' to
86
+ copy file contents.
87
+
88
+ Return a tuple (dest_name, copied): 'dest_name' is the actual name of the output file, and 'copied' is true if the
89
+ file was copied (or would have been copied, if 'dry_run' true).
90
+ """
91
+ # if the destination file already exists, we clobber it if copying, but blow up if linking. Hmmm. And I don't know
92
+ # what macostools.copyfile() does. Should definitely be consistent, and should probably blow up if destination
93
+ # exists and we would be changing it (ie. it's not already a hard/soft link to src OR (not update) and (src newer
94
+ # than dst).
95
+ from stat import S_IMODE
96
+ from stat import ST_ATIME
97
+ from stat import ST_MODE
98
+ from stat import ST_MTIME
99
+
100
+ from .modified import newer
101
+
102
+ if not os.path.isfile(src):
103
+ raise DistutilsFileError(f"can't copy '{src}': doesn't exist or not a regular file")
104
+
105
+ if os.path.isdir(dst):
106
+ dir = dst # noqa
107
+ dst = os.path.join(dst, os.path.basename(src))
108
+ else:
109
+ dir = os.path.dirname(dst) # noqa
110
+
111
+ if update and not newer(src, dst):
112
+ if verbose >= 1:
113
+ log.debug('not copying %s (output up-to-date)', src)
114
+ return (dst, 0)
115
+
116
+ try:
117
+ action = _copy_action[link]
118
+ except KeyError:
119
+ raise ValueError(f"invalid value '{link}' for 'link' argument") from None
120
+
121
+ if verbose >= 1:
122
+ if os.path.basename(dst) == os.path.basename(src):
123
+ log.info('%s %s -> %s', action, src, dir)
124
+ else:
125
+ log.info('%s %s -> %s', action, src, dst)
126
+
127
+ if dry_run:
128
+ return (dst, 1)
129
+
130
+ # If linking (hard or symbolic), use the appropriate system call (Unix only, of course, but that's the caller's
131
+ # responsibility)
132
+ elif link == 'hard':
133
+ if not (os.path.exists(dst) and os.path.samefile(src, dst)):
134
+ try:
135
+ os.link(src, dst)
136
+ except OSError:
137
+ # If hard linking fails, fall back on copying file (some special filesystems don't support hard linking
138
+ # even under Unix, see issue #8876).
139
+ pass
140
+ else:
141
+ return (dst, 1)
142
+ elif link == 'sym':
143
+ if not (os.path.exists(dst) and os.path.samefile(src, dst)):
144
+ os.symlink(src, dst)
145
+ return (dst, 1)
146
+
147
+ # Otherwise (non-Mac, not linking), copy the file contents and (optionally) copy the times and mode.
148
+ _copy_file_contents(src, dst)
149
+ if preserve_mode or preserve_times:
150
+ st = os.stat(src)
151
+
152
+ # According to David Ascher <da@ski.org>, utime() should be done before chmod() (at least under NT).
153
+ if preserve_times:
154
+ os.utime(dst, (st[ST_ATIME], st[ST_MTIME]))
155
+ if preserve_mode:
156
+ os.chmod(dst, S_IMODE(st[ST_MODE]))
157
+
158
+ return (dst, 1)
159
+
160
+
161
+ # I suspect this is Unix-specific -- need porting help!
162
+ def move_file(src, dst, verbose=1, dry_run=False): # noqa: C901
163
+ """
164
+ Move a file 'src' to 'dst'. If 'dst' is a directory, the file will be moved into it with the same name; otherwise,
165
+ 'src' is just renamed to 'dst'. Return the new full name of the file.
166
+
167
+ Handles cross-device moves on Unix using 'copy_file()'. What about other systems???
168
+ """
169
+ import errno
170
+ from os.path import basename
171
+ from os.path import dirname
172
+ from os.path import exists
173
+ from os.path import isdir
174
+ from os.path import isfile
175
+
176
+ if verbose >= 1:
177
+ log.info('moving %s -> %s', src, dst)
178
+
179
+ if dry_run:
180
+ return dst
181
+
182
+ if not isfile(src):
183
+ raise DistutilsFileError(f"can't move '{src}': not a regular file")
184
+
185
+ if isdir(dst):
186
+ dst = os.path.join(dst, basename(src))
187
+ elif exists(dst):
188
+ raise DistutilsFileError(f"can't move '{src}': destination '{dst}' already exists")
189
+
190
+ if not isdir(dirname(dst)):
191
+ raise DistutilsFileError(f"can't move '{src}': destination '{dst}' not a valid path")
192
+
193
+ copy_it = False
194
+ try:
195
+ os.rename(src, dst)
196
+ except OSError as e:
197
+ (num, msg) = e.args
198
+ if num == errno.EXDEV:
199
+ copy_it = True
200
+ else:
201
+ raise DistutilsFileError(f"couldn't move '{src}' to '{dst}': {msg}") from None
202
+
203
+ if copy_it:
204
+ copy_file(src, dst, verbose=verbose)
205
+ try:
206
+ os.unlink(src)
207
+ except OSError as e:
208
+ (num, msg) = e.args
209
+ with contextlib.suppress(OSError):
210
+ os.unlink(dst)
211
+ raise DistutilsFileError(
212
+ f"couldn't move '{src}' to '{dst}' by copy/delete: "
213
+ f"delete '{src}' failed: {msg}",
214
+ ) from None
215
+
216
+ return dst
@@ -0,0 +1,47 @@
1
+ """Timestamp comparison of files and groups of files."""
2
+ import os.path
3
+
4
+ from .errors import DistutilsFileError
5
+
6
+
7
+ def _newer(source, target):
8
+ return not os.path.exists(target) or (os.path.getmtime(source) > os.path.getmtime(target))
9
+
10
+
11
+ def newer(source, target):
12
+ """
13
+ Is source modified more recently than target.
14
+
15
+ Returns True if 'source' is modified more recently than 'target' or if 'target' does not exist.
16
+
17
+ Raises DistutilsFileError if 'source' does not exist.
18
+ """
19
+ if not os.path.exists(source):
20
+ raise DistutilsFileError(f"file '{os.path.abspath(source)}' does not exist")
21
+
22
+ return _newer(source, target)
23
+
24
+
25
+ def newer_group(sources, target, missing='error'):
26
+ """
27
+ Is target out-of-date with respect to any file in sources.
28
+
29
+ Return True if 'target' is out-of-date with respect to any file listed in 'sources'. In other words, if 'target'
30
+ exists and is newer than every file in 'sources', return False; otherwise return True. ``missing`` controls how to
31
+ handle a missing source file:
32
+
33
+ - error (default): allow the ``stat()`` call to fail.
34
+ - ignore: silently disregard any missing source files.
35
+ - newer: treat missing source files as "target out of date". This mode is handy in "dry-run" mode: it will pretend
36
+ to carry out commands that wouldn't work because inputs are missing, but that doesn't matter because dry-run won't
37
+ run the commands.
38
+ """
39
+
40
+ def missing_as_newer(source):
41
+ return missing == 'newer' and not os.path.exists(source)
42
+
43
+ ignored = os.path.exists if missing == 'ignore' else None
44
+ return any(
45
+ missing_as_newer(source) or _newer(source, target)
46
+ for source in filter(ignored, sources)
47
+ )
@@ -0,0 +1,103 @@
1
+ """
2
+ Provides the 'spawn()' function, a front-end to various platform-
3
+ specific functions for launching another program in a sub-process.
4
+ Also provides the 'find_executable()' to search the path for a given
5
+ executable name.
6
+ """
7
+ import logging
8
+ import os
9
+ import subprocess
10
+ import sys
11
+
12
+ from .errors import DistutilsExecError
13
+
14
+
15
+ log = logging.getLogger(__name__)
16
+
17
+
18
+ def spawn(cmd, search_path=1, verbose=0, dry_run=False, env=None, debug=False): # noqa: C901
19
+ """
20
+ Run another program, specified as a command list 'cmd', in a new process.
21
+
22
+ 'cmd' is just the argument list for the new process, ie. cmd[0] is the program to run and cmd[1:] are the rest of
23
+ its arguments. There is no way to run a program with a name different from that of its executable.
24
+
25
+ If 'search_path' is true (the default), the system's executable search path will be used to find the program;
26
+ otherwise, cmd[0] must be the exact path to the executable. If 'dry_run' is true, the command will not actually be
27
+ run.
28
+
29
+ Raise DistutilsExecError if running the program fails in any way; just return on success.
30
+ """
31
+ # cmd is documented as a list, but just in case some code passes a tuple in, protect our %-formatting code against
32
+ # horrible death
33
+ cmd = list(cmd)
34
+
35
+ log.info(subprocess.list2cmdline(cmd))
36
+ if dry_run:
37
+ return
38
+
39
+ if search_path:
40
+ executable = find_executable(cmd[0])
41
+ if executable is not None:
42
+ cmd[0] = executable
43
+
44
+ env = env if env is not None else dict(os.environ)
45
+
46
+ if sys.platform == 'darwin':
47
+ from .util import MACOSX_VERSION_VAR
48
+ from .util import get_macosx_target_ver
49
+
50
+ macosx_target_ver = get_macosx_target_ver()
51
+ if macosx_target_ver:
52
+ env[MACOSX_VERSION_VAR] = macosx_target_ver
53
+
54
+ try:
55
+ proc = subprocess.Popen(cmd, env=env)
56
+ proc.wait()
57
+ exitcode = proc.returncode
58
+ except OSError as exc:
59
+ if not debug:
60
+ cmd = cmd[0]
61
+ raise DistutilsExecError(f'command {cmd!r} failed: {exc.args[-1]}') from exc
62
+
63
+ if exitcode:
64
+ if not debug:
65
+ cmd = cmd[0]
66
+ raise DistutilsExecError(f'command {cmd!r} failed with exit code {exitcode}')
67
+
68
+
69
+ def find_executable(executable, path=None):
70
+ """
71
+ Tries to find 'executable' in the directories listed in 'path'.
72
+
73
+ A string listing directories separated by 'os.pathsep'; defaults to os.environ['PATH']. Returns the complete
74
+ filename or None if not found.
75
+ """
76
+ _, ext = os.path.splitext(executable)
77
+ if (sys.platform == 'win32') and (ext != '.exe'):
78
+ executable = executable + '.exe'
79
+
80
+ if os.path.isfile(executable):
81
+ return executable
82
+
83
+ if path is None:
84
+ path = os.environ.get('PATH', None)
85
+ if path is None:
86
+ try:
87
+ path = os.confstr('CS_PATH')
88
+ except (AttributeError, ValueError):
89
+ # os.confstr() or CS_PATH is not available
90
+ path = os.defpath
91
+ # bpo-35755: Don't use os.defpath if the PATH environment variable is set to an empty string
92
+
93
+ # PATH='' doesn't match, whereas PATH=':' looks in the current directory
94
+ if not path:
95
+ return None
96
+
97
+ paths = path.split(os.pathsep)
98
+ for p in paths:
99
+ f = os.path.join(p, executable)
100
+ if os.path.isfile(f):
101
+ # the file exists, we have a shot at spawn working
102
+ return f
103
+ return None