omdev 0.0.0.dev196__tar.gz → 0.0.0.dev198__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (197) hide show
  1. {omdev-0.0.0.dev196/omdev.egg-info → omdev-0.0.0.dev198}/PKG-INFO +2 -2
  2. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/.manifests.json +12 -0
  3. omdev-0.0.0.dev198/omdev/tools/linehisto.py +335 -0
  4. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198/omdev.egg-info}/PKG-INFO +2 -2
  5. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev.egg-info/SOURCES.txt +1 -0
  6. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev.egg-info/requires.txt +1 -1
  7. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/pyproject.toml +2 -2
  8. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/LICENSE +0 -0
  9. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/MANIFEST.in +0 -0
  10. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/README.rst +0 -0
  11. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/__about__.py +0 -0
  12. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/__init__.py +0 -0
  13. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/amalg/__init__.py +0 -0
  14. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/amalg/__main__.py +0 -0
  15. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/amalg/gen.py +0 -0
  16. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/amalg/imports.py +0 -0
  17. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/amalg/main.py +0 -0
  18. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/amalg/manifests.py +0 -0
  19. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/amalg/resources.py +0 -0
  20. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/amalg/srcfiles.py +0 -0
  21. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/amalg/strip.py +0 -0
  22. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/amalg/types.py +0 -0
  23. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/amalg/typing.py +0 -0
  24. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/antlr/__init__.py +0 -0
  25. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/antlr/consts.py +0 -0
  26. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/antlr/gen.py +0 -0
  27. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/bracepy.py +0 -0
  28. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cache/__init__.py +0 -0
  29. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cache/compute/__init__.py +0 -0
  30. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cache/compute/cache.py +0 -0
  31. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cache/compute/contexts.py +0 -0
  32. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cache/compute/currents.py +0 -0
  33. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cache/compute/fns.py +0 -0
  34. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cache/compute/resolvers.py +0 -0
  35. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cache/compute/storage.py +0 -0
  36. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cache/compute/types.py +0 -0
  37. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cache/data/__init__.py +0 -0
  38. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cache/data/actions.py +0 -0
  39. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cache/data/cache.py +0 -0
  40. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cache/data/consts.py +0 -0
  41. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cache/data/defaults.py +0 -0
  42. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cache/data/manifests.py +0 -0
  43. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cache/data/specs.py +0 -0
  44. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cexts/__init__.py +0 -0
  45. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cexts/_boilerplate.cc +0 -0
  46. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cexts/_distutils/LICENSE +0 -0
  47. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cexts/_distutils/__init__.py +0 -0
  48. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cexts/_distutils/build_ext.py +0 -0
  49. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cexts/_distutils/compilers/__init__.py +0 -0
  50. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cexts/_distutils/compilers/ccompiler.py +0 -0
  51. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cexts/_distutils/compilers/options.py +0 -0
  52. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cexts/_distutils/compilers/unixccompiler.py +0 -0
  53. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cexts/_distutils/dir_util.py +0 -0
  54. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cexts/_distutils/errors.py +0 -0
  55. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cexts/_distutils/extension.py +0 -0
  56. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cexts/_distutils/file_util.py +0 -0
  57. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cexts/_distutils/modified.py +0 -0
  58. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cexts/_distutils/spawn.py +0 -0
  59. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cexts/_distutils/sysconfig.py +0 -0
  60. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cexts/_distutils/util.py +0 -0
  61. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cexts/_distutils/version.py +0 -0
  62. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cexts/build.py +0 -0
  63. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cexts/cmake.py +0 -0
  64. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cexts/importhook.py +0 -0
  65. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cexts/magic.py +0 -0
  66. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cexts/scan.py +0 -0
  67. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/classdot.py +0 -0
  68. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cli/__init__.py +0 -0
  69. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cli/__main__.py +0 -0
  70. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cli/_pathhack.py +0 -0
  71. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cli/clicli.py +0 -0
  72. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cli/install.py +0 -0
  73. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cli/main.py +0 -0
  74. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cli/managers.py +0 -0
  75. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cli/types.py +0 -0
  76. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/clipboard/__init__.py +0 -0
  77. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/clipboard/clipboard.py +0 -0
  78. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/clipboard/darwin_cf.py +0 -0
  79. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/clipboard/linux_x11.py +0 -0
  80. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/cmake.py +0 -0
  81. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/findimports.py +0 -0
  82. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/git/__init__.py +0 -0
  83. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/git/revisions.py +0 -0
  84. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/git/status.py +0 -0
  85. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/git/subtrees.py +0 -0
  86. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/imgur.py +0 -0
  87. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/interp/__init__.py +0 -0
  88. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/interp/__main__.py +0 -0
  89. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/interp/cli.py +0 -0
  90. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/interp/default.py +0 -0
  91. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/interp/inject.py +0 -0
  92. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/interp/inspect.py +0 -0
  93. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/interp/providers/__init__.py +0 -0
  94. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/interp/providers/base.py +0 -0
  95. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/interp/providers/inject.py +0 -0
  96. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/interp/providers/running.py +0 -0
  97. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/interp/providers/standalone.py +0 -0
  98. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/interp/providers/system.py +0 -0
  99. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/interp/pyenv/__init__.py +0 -0
  100. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/interp/pyenv/inject.py +0 -0
  101. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/interp/pyenv/install.py +0 -0
  102. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/interp/pyenv/provider.py +0 -0
  103. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/interp/pyenv/pyenv.py +0 -0
  104. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/interp/resolvers.py +0 -0
  105. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/interp/types.py +0 -0
  106. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/interp/uv/__init__.py +0 -0
  107. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/interp/uv/inject.py +0 -0
  108. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/interp/uv/provider.py +0 -0
  109. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/interp/uv/uv.py +0 -0
  110. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/interp/venvs.py +0 -0
  111. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/magic/__init__.py +0 -0
  112. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/magic/__main__.py +0 -0
  113. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/magic/cli.py +0 -0
  114. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/magic/find.py +0 -0
  115. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/magic/magic.py +0 -0
  116. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/magic/prepare.py +0 -0
  117. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/magic/styles.py +0 -0
  118. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/manifests/__init__.py +0 -0
  119. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/manifests/__main__.py +0 -0
  120. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/manifests/build.py +0 -0
  121. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/manifests/main.py +0 -0
  122. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/mypy/__init__.py +0 -0
  123. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/mypy/debug.py +0 -0
  124. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/packaging/__init__.py +0 -0
  125. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/packaging/marshal.py +0 -0
  126. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/packaging/names.py +0 -0
  127. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/packaging/requires.py +0 -0
  128. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/packaging/specifiers.py +0 -0
  129. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/packaging/versions.py +0 -0
  130. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/pip.py +0 -0
  131. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/precheck/__init__.py +0 -0
  132. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/precheck/__main__.py +0 -0
  133. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/precheck/base.py +0 -0
  134. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/precheck/git.py +0 -0
  135. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/precheck/lite.py +0 -0
  136. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/precheck/main.py +0 -0
  137. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/precheck/manifests.py +0 -0
  138. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/precheck/scripts.py +0 -0
  139. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/ptk/__init__.py +0 -0
  140. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/ptk/apps/__init__.py +0 -0
  141. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/ptk/apps/ncdu.py +0 -0
  142. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/pycharm/__init__.py +0 -0
  143. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/pycharm/__main__.py +0 -0
  144. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/pycharm/cli.py +0 -0
  145. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/pyproject/__init__.py +0 -0
  146. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/pyproject/__main__.py +0 -0
  147. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/pyproject/cexts.py +0 -0
  148. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/pyproject/cli.py +0 -0
  149. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/pyproject/configs.py +0 -0
  150. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/pyproject/inject.py +0 -0
  151. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/pyproject/pkg.py +0 -0
  152. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/pyproject/reqs.py +0 -0
  153. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/pyproject/resources/__init__.py +0 -0
  154. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/pyproject/resources/docker-dev.sh +0 -0
  155. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/pyproject/resources/python.sh +0 -0
  156. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/pyproject/venvs.py +0 -0
  157. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/revisions.py +0 -0
  158. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/scripts/__init__.py +0 -0
  159. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/scripts/bumpversion.py +0 -0
  160. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/scripts/execrss.py +0 -0
  161. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/scripts/exectime.py +0 -0
  162. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/scripts/importtrace.py +0 -0
  163. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/scripts/interp.py +0 -0
  164. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/scripts/pyproject.py +0 -0
  165. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/scripts/slowcat.py +0 -0
  166. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/scripts/tmpexec.py +0 -0
  167. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/secrets.py +0 -0
  168. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/tagstrings.py +0 -0
  169. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/tokens.py +0 -0
  170. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/tools/__init__.py +0 -0
  171. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/tools/cloc.py +0 -0
  172. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/tools/doc.py +0 -0
  173. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/tools/docker.py +0 -0
  174. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/tools/git.py +0 -0
  175. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/tools/importscan.py +0 -0
  176. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/tools/json/__init__.py +0 -0
  177. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/tools/json/__main__.py +0 -0
  178. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/tools/json/cli.py +0 -0
  179. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/tools/json/formats.py +0 -0
  180. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/tools/json/io.py +0 -0
  181. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/tools/json/parsing.py +0 -0
  182. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/tools/json/processing.py +0 -0
  183. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/tools/json/rendering.py +0 -0
  184. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/tools/mkrelimp.py +0 -0
  185. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/tools/notebook.py +0 -0
  186. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/tools/pawk/__init__.py +0 -0
  187. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/tools/pawk/__main__.py +0 -0
  188. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/tools/pawk/pawk.py +0 -0
  189. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/tools/pip.py +0 -0
  190. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/tools/prof.py +0 -0
  191. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/tools/qr.py +0 -0
  192. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/tools/sqlrepl.py +0 -0
  193. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev/wheelfile.py +0 -0
  194. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev.egg-info/dependency_links.txt +0 -0
  195. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev.egg-info/entry_points.txt +0 -0
  196. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/omdev.egg-info/top_level.txt +0 -0
  197. {omdev-0.0.0.dev196 → omdev-0.0.0.dev198}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: omdev
3
- Version: 0.0.0.dev196
3
+ Version: 0.0.0.dev198
4
4
  Summary: omdev
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -12,7 +12,7 @@ Classifier: Operating System :: OS Independent
12
12
  Classifier: Operating System :: POSIX
13
13
  Requires-Python: >=3.12
14
14
  License-File: LICENSE
15
- Requires-Dist: omlish==0.0.0.dev196
15
+ Requires-Dist: omlish==0.0.0.dev198
16
16
  Provides-Extra: all
17
17
  Requires-Dist: black~=24.10; extra == "all"
18
18
  Requires-Dist: pycparser~=2.22; extra == "all"
@@ -302,6 +302,18 @@
302
302
  }
303
303
  }
304
304
  },
305
+ {
306
+ "module": ".tools.linehisto",
307
+ "attr": "_CLI_MODULE",
308
+ "file": "omdev/tools/linehisto.py",
309
+ "line": 330,
310
+ "value": {
311
+ "$.cli.types.CliModule": {
312
+ "cmd_name": "linehisto",
313
+ "mod_name": "omdev.tools.linehisto"
314
+ }
315
+ }
316
+ },
305
317
  {
306
318
  "module": ".tools.mkrelimp",
307
319
  "attr": "_CLI_MODULE",
@@ -0,0 +1,335 @@
1
+ """
2
+ TODO:
3
+ - cmd line options
4
+ - truncation
5
+ - mean/min/max/median/stddev
6
+ - delta mean/min/max/median/stddev
7
+ - heat - red rapidly changing blue stale
8
+ - paging
9
+ - find
10
+ - stdin/stdout redir (ttyname(0))
11
+ - graph
12
+ """
13
+ import curses
14
+ import heapq
15
+ import operator
16
+ import sys
17
+ import time
18
+ import typing as ta
19
+
20
+ from ..cli import CliModule
21
+
22
+
23
+ ##
24
+
25
+
26
+ def with_timer(interval=5.):
27
+ def outer(fn):
28
+ start = time.time()
29
+ last = start
30
+
31
+ def inner(*args, **kwargs):
32
+ nonlocal last
33
+
34
+ now = time.time()
35
+ if (now - last) < interval:
36
+ return None
37
+
38
+ last = now
39
+ return fn(*args, **kwargs)
40
+
41
+ return inner
42
+
43
+ return outer
44
+
45
+
46
+ def calc_percent(a: float, b: float) -> float:
47
+ if not a or not b:
48
+ return 0.
49
+ return ((a * 1e9) // (b * 1e5)) / 100.
50
+
51
+
52
+ ##
53
+
54
+
55
+ class KeyedHisto:
56
+ def __init__(
57
+ self,
58
+ *,
59
+ max_entries: int | None = None,
60
+ ) -> None:
61
+ super().__init__()
62
+
63
+ self.entries: dict[str, int] = {}
64
+ self.total_seen = 0
65
+ self.total_evicted = 0
66
+
67
+ self.max_entries = max_entries
68
+ if max_entries is not None:
69
+ self.eviction_len = int(max_entries * 2)
70
+
71
+ self.num_evicted = 0
72
+
73
+ def __len__(self) -> int:
74
+ return len(self.entries)
75
+
76
+ @property
77
+ def total_tracked(self) -> int:
78
+ return self.total_seen - self.total_evicted
79
+
80
+ def inc(self, key: str, n: int = 1) -> int:
81
+ if self.max_entries is not None and len(self) >= self.eviction_len:
82
+ self.evict(len(self) - self.max_entries)
83
+
84
+ self.total_seen += n
85
+
86
+ ct = self.entries.get(key, 0) + n
87
+ self.entries[key] = ct
88
+
89
+ return ct
90
+
91
+ @property
92
+ def items(self) -> ta.Iterable[tuple[str, int]]:
93
+ return self.entries.items()
94
+
95
+ @property
96
+ def sorted(self) -> list[tuple[str, int]]:
97
+ items = sorted(self.items, key=operator.itemgetter(1))
98
+ return items[::-1]
99
+
100
+ def evict(self, n: int = 1) -> None:
101
+ self.num_evicted += n
102
+
103
+ for key, ct in heapq.nsmallest(n, self.items, key=operator.itemgetter(1)):
104
+ self.total_evicted += ct
105
+
106
+ del self.entries[key]
107
+
108
+ def nlargest(self, n: int = 20) -> list[tuple[str, int]]:
109
+ return heapq.nlargest(n, self.items, key=operator.itemgetter(1))
110
+
111
+ def nsmallest(self, n: int = 20) -> list[tuple[str, int]]:
112
+ return heapq.nsmallest(n, self.items, key=operator.itemgetter(1))
113
+
114
+
115
+ class KeyedHistoRenderer:
116
+ def __init__(
117
+ self,
118
+ histo: KeyedHisto,
119
+ *,
120
+ max_lines: int | None = None,
121
+ ) -> None:
122
+ super().__init__()
123
+
124
+ self.histo = histo
125
+ self.max_lines = max_lines
126
+
127
+ @property
128
+ def entries_to_render(self) -> list[tuple[str, int]]:
129
+ if self.max_lines is None:
130
+ return list(self.histo.sorted)
131
+
132
+ nlines = min(self.max_lines, len(self.histo))
133
+
134
+ return self.histo.nlargest(nlines)
135
+
136
+ def render_header(self, count_width: int) -> str:
137
+ header = 'count : % sen : % tkd : line'
138
+
139
+ if count_width > 5:
140
+ header = (' ' * (count_width - 5)) + header
141
+
142
+ return header
143
+
144
+ def render_entry(self, entry: tuple[str, int], count_width: int) -> str:
145
+ line, count = entry
146
+
147
+ line_fmt = '%' + str(count_width) + 'd : %5s : %5s : %s'
148
+
149
+ percent_seen_str = f'{calc_percent(count, self.histo.total_seen):3.2f}'
150
+ percent_tracked_str = f'{calc_percent(count, self.histo.total_tracked):3.2f}'
151
+
152
+ return line_fmt % (count, percent_seen_str, percent_tracked_str, line)
153
+
154
+ def render_entries(self, entries: ta.Iterable[tuple[str, int]], count_width: int) -> list[str]:
155
+ return [self.render_entry(entry, count_width) for entry in entries]
156
+
157
+ def render_status(self) -> str:
158
+ parts = [f'{self.histo.total_seen} total seen']
159
+
160
+ total_tracked_percent = calc_percent(self.histo.total_tracked, self.histo.total_seen)
161
+ parts.extend([
162
+ f'{len(self.histo)} tracked',
163
+ f'{self.histo.total_tracked} / {total_tracked_percent:.2f} % total tracked',
164
+ ])
165
+
166
+ parts.extend([
167
+ f'{self.histo.num_evicted} evicted',
168
+ f'{self.histo.total_evicted} / {100.0 - total_tracked_percent:.2f} % total evicted',
169
+ ])
170
+
171
+ duplicate_evictions = self.histo.total_evicted - self.histo.num_evicted
172
+ parts.append(
173
+ f'{duplicate_evictions} / {calc_percent(duplicate_evictions, self.histo.total_evicted):.2f} '
174
+ f'% duplicate evictions',
175
+ )
176
+
177
+ # tracked % + duplicate evicted %
178
+ parts.append(
179
+ f'{calc_percent(self.histo.total_tracked - duplicate_evictions, self.histo.total_seen):.2f} % correct',
180
+ )
181
+
182
+ return ', '.join(parts)
183
+
184
+ class Rendered(ta.NamedTuple):
185
+ status_line: str
186
+ header_line: str
187
+ entry_lines: list[str]
188
+
189
+ def render(self, entries: ta.Sequence[tuple[str, int]] | None = None) -> Rendered:
190
+ if entries is None:
191
+ entries = self.entries_to_render
192
+
193
+ max_count = entries[0][1] if entries else 0
194
+ count_width = len(str(max_count))
195
+
196
+ status_line = self.render_status()
197
+ header_line = self.render_header(count_width)
198
+ entry_lines = self.render_entries(entries, count_width)
199
+
200
+ return self.Rendered(
201
+ status_line,
202
+ header_line,
203
+ entry_lines,
204
+ )
205
+
206
+ def render_to_str(self) -> str:
207
+ status_line, header_line, entry_lines = self.render()
208
+
209
+ return '\n'.join([status_line, '', header_line, *entry_lines, ''])
210
+
211
+
212
+ class CursesKeyedHistoRenderer(KeyedHistoRenderer):
213
+ color_normal = 0
214
+ color_green = 1
215
+ color_yellow = 2
216
+ color_red = 3
217
+
218
+ def __init__(
219
+ self,
220
+ window,
221
+ histo: KeyedHisto,
222
+ *,
223
+ redraw_interval: float = .1,
224
+ ) -> None:
225
+ self.window = window
226
+ self.redraw_interval = redraw_interval
227
+
228
+ h, w = self.window.getmaxyx()
229
+ max_lines = h - 3
230
+
231
+ self.max_line_len = w - 30
232
+
233
+ super().__init__(
234
+ histo,
235
+ max_lines=max_lines,
236
+ )
237
+
238
+ self.timed_redraw = with_timer(redraw_interval)(self.draw)
239
+
240
+ self.last_drawn_entries: list[tuple[str, int]] = []
241
+
242
+ curses.init_pair(self.color_green, curses.COLOR_GREEN, curses.COLOR_BLACK)
243
+ curses.init_pair(self.color_yellow, curses.COLOR_YELLOW, curses.COLOR_BLACK)
244
+ curses.init_pair(self.color_red, curses.COLOR_RED, curses.COLOR_BLACK)
245
+
246
+ def get_entry_color(
247
+ self,
248
+ cur_pos: int,
249
+ last_pos: int | None,
250
+ ) -> int:
251
+ if last_pos is None:
252
+ return self.color_green
253
+ elif last_pos > cur_pos:
254
+ return self.color_yellow
255
+ elif last_pos < cur_pos:
256
+ return self.color_red
257
+ else:
258
+ return self.color_normal
259
+
260
+ def get_entry_colors(self, entries: ta.Iterable[tuple[str, int]]) -> list[int]:
261
+ last_pos_map = {s: i for i, (s, _) in enumerate(self.last_drawn_entries)}
262
+
263
+ return [
264
+ self.get_entry_color(i, last_pos_map.get(key))
265
+ for i, (key, _) in enumerate(entries)
266
+ ]
267
+
268
+ def draw(self) -> None:
269
+ entries = self.entries_to_render
270
+
271
+ status_line, header_line, entry_lines = self.render(entries)
272
+ entry_colors = self.get_entry_colors(entries)
273
+
274
+ self.last_drawn_entries = entries
275
+
276
+ self.window.clear()
277
+ self.window.addstr(0, 0, status_line)
278
+ self.window.addstr(2, 0, header_line)
279
+
280
+ for i, (line, color) in enumerate(zip(entry_lines, entry_colors)):
281
+ self.window.addstr(i + 3, 0, line[:120], curses.color_pair(color))
282
+
283
+ self.window.refresh()
284
+
285
+
286
+ def main() -> None:
287
+ screen = curses.initscr()
288
+ curses.start_color()
289
+ curses.curs_set(0)
290
+
291
+ histo = KeyedHisto(max_entries=10_000)
292
+ renderer = CursesKeyedHistoRenderer(screen, histo)
293
+
294
+ try:
295
+ while True:
296
+ try:
297
+ line = sys.stdin.readline()
298
+ except UnicodeDecodeError:
299
+ # FIXME
300
+ continue
301
+
302
+ if not line:
303
+ break
304
+
305
+ if len(line) > renderer.max_line_len:
306
+ line = line[renderer.max_line_len:]
307
+
308
+ line = line.strip()
309
+
310
+ if not line:
311
+ continue
312
+
313
+ histo.inc(line)
314
+ renderer.timed_redraw()
315
+
316
+ # screen.nodelay(1)
317
+ # ch = screen.getch()
318
+ # if ch != curses.ERR:
319
+ # histo.inc(ch, 100)
320
+
321
+ except (OSError, KeyboardInterrupt):
322
+ pass
323
+
324
+ finally:
325
+ curses.endwin()
326
+
327
+ sys.stdout.write(KeyedHistoRenderer(histo).render_to_str())
328
+
329
+
330
+ # @omlish-manifest
331
+ _CLI_MODULE = CliModule('linehisto', __name__)
332
+
333
+
334
+ if __name__ == '__main__':
335
+ main()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: omdev
3
- Version: 0.0.0.dev196
3
+ Version: 0.0.0.dev198
4
4
  Summary: omdev
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -12,7 +12,7 @@ Classifier: Operating System :: OS Independent
12
12
  Classifier: Operating System :: POSIX
13
13
  Requires-Python: >=3.12
14
14
  License-File: LICENSE
15
- Requires-Dist: omlish==0.0.0.dev196
15
+ Requires-Dist: omlish==0.0.0.dev198
16
16
  Provides-Extra: all
17
17
  Requires-Dist: black~=24.10; extra == "all"
18
18
  Requires-Dist: pycparser~=2.22; extra == "all"
@@ -175,6 +175,7 @@ omdev/tools/doc.py
175
175
  omdev/tools/docker.py
176
176
  omdev/tools/git.py
177
177
  omdev/tools/importscan.py
178
+ omdev/tools/linehisto.py
178
179
  omdev/tools/mkrelimp.py
179
180
  omdev/tools/notebook.py
180
181
  omdev/tools/pip.py
@@ -1,4 +1,4 @@
1
- omlish==0.0.0.dev196
1
+ omlish==0.0.0.dev198
2
2
 
3
3
  [all]
4
4
  black~=24.10
@@ -12,7 +12,7 @@ authors = [
12
12
  urls = {source = 'https://github.com/wrmsr/omlish'}
13
13
  license = {text = 'BSD-3-Clause'}
14
14
  requires-python = '>=3.12'
15
- version = '0.0.0.dev196'
15
+ version = '0.0.0.dev198'
16
16
  classifiers = [
17
17
  'License :: OSI Approved :: BSD License',
18
18
  'Development Status :: 2 - Pre-Alpha',
@@ -22,7 +22,7 @@ classifiers = [
22
22
  ]
23
23
  description = 'omdev'
24
24
  dependencies = [
25
- 'omlish == 0.0.0.dev196',
25
+ 'omlish == 0.0.0.dev198',
26
26
  ]
27
27
 
28
28
  [project.optional-dependencies]
File without changes
File without changes
File without changes
File without changes
File without changes