rda-python-miscs 2.0.11__tar.gz → 2.0.13__tar.gz

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 (53) hide show
  1. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/PKG-INFO +1 -1
  2. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/pyproject.toml +1 -1
  3. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/pg_rst.py +117 -12
  4. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs.egg-info/PKG-INFO +1 -1
  5. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/LICENSE +0 -0
  6. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/MANIFEST.in +0 -0
  7. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/README.md +0 -0
  8. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/setup.cfg +0 -0
  9. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/__init__.py +0 -0
  10. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/bash_qsub.py +0 -0
  11. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/bashqsub.py +0 -0
  12. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/bashqsub.usg +0 -0
  13. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/gdex_ls.py +0 -0
  14. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/gdexls.py +0 -0
  15. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/gdexls.usg +0 -0
  16. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/gdexls_standalone.py +0 -0
  17. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/pg_docs.py +0 -0
  18. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/pg_wget.py +0 -0
  19. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/pgwget.py +0 -0
  20. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/rda_cp.py +0 -0
  21. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/rda_kill.py +0 -0
  22. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/rda_mod.py +0 -0
  23. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/rda_own.py +0 -0
  24. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/rda_ps.py +0 -0
  25. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/rda_sub.py +0 -0
  26. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/rda_zip.py +0 -0
  27. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/rdacp.py +0 -0
  28. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/rdacp.usg +0 -0
  29. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/rdakill.py +0 -0
  30. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/rdakill.usg +0 -0
  31. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/rdals.py +0 -0
  32. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/rdals.usg +0 -0
  33. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/rdamod.py +0 -0
  34. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/rdamod.usg +0 -0
  35. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/rdaown.py +0 -0
  36. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/rdaown.usg +0 -0
  37. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/rdaps.py +0 -0
  38. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/rdaps.usg +0 -0
  39. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/rdasub.py +0 -0
  40. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/rdasub.usg +0 -0
  41. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/rdazip.py +0 -0
  42. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/rdazip.usg +0 -0
  43. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/rst_templates/index.rst.temp +0 -0
  44. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/rst_templates/section.rst.temp +0 -0
  45. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/tcsh_qsub.py +0 -0
  46. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/tcshqsub.py +0 -0
  47. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs/tcshqsub.usg +0 -0
  48. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs.egg-info/SOURCES.txt +0 -0
  49. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs.egg-info/dependency_links.txt +0 -0
  50. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs.egg-info/entry_points.txt +0 -0
  51. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs.egg-info/requires.txt +0 -0
  52. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/src/rda_python_miscs.egg-info/top_level.txt +0 -0
  53. {rda_python_miscs-2.0.11 → rda_python_miscs-2.0.13}/tests/test_miscs.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rda_python_miscs
3
- Version: 2.0.11
3
+ Version: 2.0.13
4
4
  Summary: RDA Python package to hold RDA miscellaneous utility programs
5
5
  Author-email: Zaihua Ji <zji@ucar.edu>
6
6
  Project-URL: Homepage, https://github.com/NCAR/rda-python-miscs
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
6
6
 
7
7
  [project]
8
8
  name = "rda_python_miscs"
9
- version = "2.0.11"
9
+ version = "2.0.13"
10
10
  authors = [
11
11
  { name="Zaihua Ji", email="zji@ucar.edu" },
12
12
  ]
@@ -18,6 +18,7 @@ import re
18
18
  import inspect
19
19
  import argparse
20
20
  import importlib
21
+ import importlib.util
21
22
  from os import path as op
22
23
  from rda_python_common.pg_file import PgFile
23
24
  from rda_python_common.pg_util import PgUtil
@@ -872,6 +873,13 @@ class PgRST(PgFile, PgUtil):
872
873
  str: RST-formatted table or list content.
873
874
  """
874
875
  line0 = lines[0]
876
+ if any('-->' in line for line in lines):
877
+ max_width = max(len(line) for line in lines)
878
+ content = ".. code-block:: none\n\n"
879
+ for line in lines:
880
+ content += " " + line.ljust(max_width) + "\n"
881
+ content += "\n"
882
+ return content
875
883
  ms = re.match(r'^\s+-\s+(.*)', line0)
876
884
  if ms:
877
885
  content = "* " + self.replace_option_link(ms.group(1), secid, 1)
@@ -1164,6 +1172,62 @@ class PgRST(PgFile, PgUtil):
1164
1172
 
1165
1173
  return opts, alias, origin
1166
1174
 
1175
+ def load_opts_alias_from_pyfile(self, pyfile):
1176
+ """Load OPTS and ALIAS from a Python file given by path.
1177
+
1178
+ Uses ``importlib.util.spec_from_file_location`` to import the file
1179
+ without requiring it to be on ``sys.path``. Resolution order mirrors
1180
+ :meth:`load_opts_alias`: class attributes first, then module-level.
1181
+
1182
+ Args:
1183
+ pyfile (str): Absolute or relative path to the Python source file.
1184
+
1185
+ Returns:
1186
+ tuple[dict, dict]: ``(OPTS, ALIAS)`` where ALIAS defaults to ``{}``
1187
+ when not found.
1188
+
1189
+ Raises:
1190
+ SystemExit: via :func:`PgLOG.pglog` (``LGWNEX``) if the file
1191
+ cannot be loaded or ``OPTS`` cannot be found.
1192
+ """
1193
+ pyfile = op.abspath(pyfile)
1194
+ modname = op.splitext(op.basename(pyfile))[0]
1195
+ try:
1196
+ spec = importlib.util.spec_from_file_location(modname, pyfile)
1197
+ mod = importlib.util.module_from_spec(spec)
1198
+ spec.loader.exec_module(mod)
1199
+ except Exception as exc:
1200
+ self.pglog(
1201
+ "Cannot load module from '{}': {}".format(pyfile, exc),
1202
+ self.LGWNEX,
1203
+ )
1204
+
1205
+ cls = next(
1206
+ (obj for _, obj in inspect.getmembers(mod, inspect.isclass)
1207
+ if obj.__module__ == modname),
1208
+ None,
1209
+ )
1210
+
1211
+ if cls is not None:
1212
+ obj = cls()
1213
+ opts = getattr(obj, 'OPTS', None)
1214
+ alias = getattr(obj, 'ALIAS', None)
1215
+ else:
1216
+ opts = getattr(mod, 'OPTS', None)
1217
+ alias = getattr(mod, 'ALIAS', None)
1218
+
1219
+ if opts is None:
1220
+ self.pglog(
1221
+ "File '{}' does not define OPTS (checked class and "
1222
+ "module level)".format(pyfile),
1223
+ self.LGWNEX,
1224
+ )
1225
+
1226
+ if alias is None:
1227
+ alias = {}
1228
+
1229
+ return opts, alias
1230
+
1167
1231
 
1168
1232
  # ---------------------------------------------------------------------------
1169
1233
  # Command-line entry point
@@ -1174,40 +1238,81 @@ def main():
1174
1238
  parser = argparse.ArgumentParser(
1175
1239
  description=(
1176
1240
  "Convert a .usg help document to reStructuredText (.rst) using RST templates. "
1177
- "OPTS and ALIAS are loaded from rda_python_<docname>/<docname>.py: "
1178
- "the module is searched first for module-level OPTS/ALIAS variables, "
1179
- "then for a class defined in that module that carries both as class "
1180
- "attributes."
1241
+ "OPTS and ALIAS are loaded from rda_python_<docname>/<docname>.py "
1242
+ "(or from --pyfile if given): "
1243
+ "the module is searched first for a class that carries both as class "
1244
+ "attributes, then for module-level OPTS/ALIAS variables."
1181
1245
  ),
1182
1246
  formatter_class=argparse.RawDescriptionHelpFormatter,
1183
1247
  )
1184
1248
  parser.add_argument(
1185
1249
  'docname',
1250
+ nargs='?',
1251
+ default=None,
1186
1252
  help=(
1187
1253
  "Short document name, e.g. 'dsarch' or 'dsupdt'. "
1188
- "The module rda_python_<docname>/<docname>.py must be importable "
1189
- "and must define OPTS (and optionally ALIAS) either at module "
1190
- "level or as class attributes."
1254
+ "Required unless --usgfile is given, in which case the name is "
1255
+ "derived from the .usg filename by removing the extension."
1191
1256
  ),
1192
1257
  )
1193
1258
  parser.add_argument(
1194
- '--docdir',
1259
+ '-u', '--usgfile',
1260
+ default=None,
1261
+ metavar='FILE',
1262
+ help=(
1263
+ "Path to the .usg source document. When given, docname is derived "
1264
+ "from the filename by removing the .usg extension, and ORIGIN is set "
1265
+ "to the directory containing the file."
1266
+ ),
1267
+ )
1268
+ parser.add_argument(
1269
+ '-p', '--pyfile',
1270
+ default=None,
1271
+ metavar='FILE',
1272
+ help=(
1273
+ "Path to a Python file that defines OPTS (and optionally ALIAS) "
1274
+ "either at module level or as class attributes. When given, the "
1275
+ "module-import convention (rda_python_<docname>/<docname>.py) is "
1276
+ "bypassed."
1277
+ ),
1278
+ )
1279
+ parser.add_argument(
1280
+ '-d', '--docdir',
1195
1281
  default=None,
1196
1282
  metavar='DIR',
1197
1283
  help=(
1198
1284
  "Root directory under which the per-document RST output directory "
1199
1285
  "is created (default: current working directory). "
1200
- "The final output lands in <docdir>/<docname>/."
1286
+ "The final output lands in <docdir>/."
1201
1287
  ),
1202
1288
  )
1203
1289
  args = parser.parse_args()
1204
1290
 
1205
1291
  pg = PgRST()
1206
- opts, alias, origin = pg.load_opts_alias(args.docname)
1207
- pg.DOCS['ORIGIN'] = origin
1292
+
1293
+ # Resolve docname: explicit arg takes priority, then derive from --usgfile.
1294
+ if args.docname:
1295
+ docname = args.docname
1296
+ elif args.usgfile:
1297
+ docname = op.splitext(op.basename(args.usgfile))[0]
1298
+ else:
1299
+ parser.error("docname is required when --usgfile is not given")
1300
+
1301
+ # Set ORIGIN from --usgfile directory when provided.
1302
+ if args.usgfile:
1303
+ pg.DOCS['ORIGIN'] = op.dirname(op.abspath(args.usgfile)) or os.getcwd()
1304
+
1305
+ # Load OPTS/ALIAS: from --pyfile path or via module-import convention.
1306
+ if args.pyfile:
1307
+ opts, alias = pg.load_opts_alias_from_pyfile(args.pyfile)
1308
+ else:
1309
+ opts, alias, origin = pg.load_opts_alias(docname)
1310
+ if not args.usgfile:
1311
+ pg.DOCS['ORIGIN'] = origin
1312
+
1208
1313
  if args.docdir is not None:
1209
1314
  pg.DOCS['DOCDIR'] = args.docdir
1210
- pg.process_docs(args.docname, opts, alias)
1315
+ pg.process_docs(docname, opts, alias)
1211
1316
 
1212
1317
  if __name__ == "__main__":
1213
1318
  main()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rda_python_miscs
3
- Version: 2.0.11
3
+ Version: 2.0.13
4
4
  Summary: RDA Python package to hold RDA miscellaneous utility programs
5
5
  Author-email: Zaihua Ji <zji@ucar.edu>
6
6
  Project-URL: Homepage, https://github.com/NCAR/rda-python-miscs