easydev 0.14.0__tar.gz → 0.15.0__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 (51) hide show
  1. {easydev-0.14.0 → easydev-0.15.0}/PKG-INFO +53 -4
  2. {easydev-0.14.0 → easydev-0.15.0}/README.rst +48 -0
  3. {easydev-0.14.0 → easydev-0.15.0}/easydev/easytest.py +16 -1
  4. {easydev-0.14.0 → easydev-0.15.0}/easydev/platform.py +1 -1
  5. {easydev-0.14.0 → easydev-0.15.0}/easydev/tools.py +10 -8
  6. {easydev-0.14.0 → easydev-0.15.0}/pyproject.toml +2 -2
  7. {easydev-0.14.0 → easydev-0.15.0}/COPYING +0 -0
  8. {easydev-0.14.0 → easydev-0.15.0}/easydev/__init__.py +0 -0
  9. {easydev-0.14.0 → easydev-0.15.0}/easydev/appdirs.py +0 -0
  10. {easydev-0.14.0 → easydev-0.15.0}/easydev/browser.py +0 -0
  11. {easydev-0.14.0 → easydev-0.15.0}/easydev/chunks.py +0 -0
  12. {easydev-0.14.0 → easydev-0.15.0}/easydev/codecs.py +0 -0
  13. {easydev-0.14.0 → easydev-0.15.0}/easydev/config_tools.py +0 -0
  14. {easydev-0.14.0 → easydev-0.15.0}/easydev/console.py +0 -0
  15. {easydev-0.14.0 → easydev-0.15.0}/easydev/copybutton.py +0 -0
  16. {easydev-0.14.0 → easydev-0.15.0}/easydev/decorators.py +0 -0
  17. {easydev-0.14.0 → easydev-0.15.0}/easydev/dependencies.py +0 -0
  18. {easydev-0.14.0 → easydev-0.15.0}/easydev/doc.py +0 -0
  19. {easydev-0.14.0 → easydev-0.15.0}/easydev/logging_tools.py +0 -0
  20. {easydev-0.14.0 → easydev-0.15.0}/easydev/md5tools.py +0 -0
  21. {easydev-0.14.0 → easydev-0.15.0}/easydev/misc.py +0 -0
  22. {easydev-0.14.0 → easydev-0.15.0}/easydev/multicore.py +0 -0
  23. {easydev-0.14.0 → easydev-0.15.0}/easydev/options.py +0 -0
  24. {easydev-0.14.0 → easydev-0.15.0}/easydev/paths.py +0 -0
  25. {easydev-0.14.0 → easydev-0.15.0}/easydev/profiler.py +0 -0
  26. {easydev-0.14.0 → easydev-0.15.0}/easydev/progressbar.py +0 -0
  27. {easydev-0.14.0 → easydev-0.15.0}/easydev/share/__init__.py +0 -0
  28. {easydev-0.14.0 → easydev-0.15.0}/easydev/share/copybutton.js +0 -0
  29. {easydev-0.14.0 → easydev-0.15.0}/easydev/share/themes/cno/google_footer.html +0 -0
  30. {easydev-0.14.0 → easydev-0.15.0}/easydev/share/themes/cno/google_head.html +0 -0
  31. {easydev-0.14.0 → easydev-0.15.0}/easydev/share/themes/cno/index.html +0 -0
  32. {easydev-0.14.0 → easydev-0.15.0}/easydev/share/themes/cno/indexsidebar.html +0 -0
  33. {easydev-0.14.0 → easydev-0.15.0}/easydev/share/themes/cno/layout.html +0 -0
  34. {easydev-0.14.0 → easydev-0.15.0}/easydev/share/themes/cno/static/bgfooter.png +0 -0
  35. {easydev-0.14.0 → easydev-0.15.0}/easydev/share/themes/cno/static/bgtop.png +0 -0
  36. {easydev-0.14.0 → easydev-0.15.0}/easydev/share/themes/cno/static/software.css_t +0 -0
  37. {easydev-0.14.0 → easydev-0.15.0}/easydev/share/themes/cno/static/warning.jpg +0 -0
  38. {easydev-0.14.0 → easydev-0.15.0}/easydev/share/themes/cno/theme.conf +0 -0
  39. {easydev-0.14.0 → easydev-0.15.0}/easydev/share/themes/standard/google_footer.html +0 -0
  40. {easydev-0.14.0 → easydev-0.15.0}/easydev/share/themes/standard/google_head.html +0 -0
  41. {easydev-0.14.0 → easydev-0.15.0}/easydev/share/themes/standard/index.html +0 -0
  42. {easydev-0.14.0 → easydev-0.15.0}/easydev/share/themes/standard/indexsidebar.html +0 -0
  43. {easydev-0.14.0 → easydev-0.15.0}/easydev/share/themes/standard/layout.html +0 -0
  44. {easydev-0.14.0 → easydev-0.15.0}/easydev/share/themes/standard/static/bgfooter.png +0 -0
  45. {easydev-0.14.0 → easydev-0.15.0}/easydev/share/themes/standard/static/bgtop.png +0 -0
  46. {easydev-0.14.0 → easydev-0.15.0}/easydev/share/themes/standard/static/software.css_t +0 -0
  47. {easydev-0.14.0 → easydev-0.15.0}/easydev/share/themes/standard/static/warning.jpg +0 -0
  48. {easydev-0.14.0 → easydev-0.15.0}/easydev/share/themes/standard/theme.conf +0 -0
  49. {easydev-0.14.0 → easydev-0.15.0}/easydev/sphinx_themes.py +0 -0
  50. {easydev-0.14.0 → easydev-0.15.0}/easydev/timer.py +0 -0
  51. {easydev-0.14.0 → easydev-0.15.0}/easydev/url.py +0 -0
@@ -1,12 +1,13 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: easydev
3
- Version: 0.14.0
3
+ Version: 0.15.0
4
4
  Summary: Common utilities to ease development of Python packages
5
- License: BSD-3-Clause
5
+ License-Expression: BSD-3-Clause
6
+ License-File: COPYING
6
7
  Keywords: config,decorators,development
7
8
  Author: Thomas Cokelaer
8
9
  Author-email: thomas.cokelaer@pasteur.fr
9
- Requires-Python: >=3.8,<4.0
10
+ Requires-Python: >=3.9,<4.0
10
11
  Classifier: Development Status :: 5 - Production/Stable
11
12
  Classifier: Intended Audience :: Education
12
13
  Classifier: Intended Audience :: End Users/Desktop
@@ -155,12 +156,60 @@ Multiprocessing::
155
156
  t.run()
156
157
  print(t.results)
157
158
 
159
+ Moving away from easydev
160
+ ------------------------
161
+
162
+ easydev dates from a time when Python lacked many small conveniences. Most of
163
+ its tools now have a standard-library or well-maintained third-party
164
+ replacement, and new projects should not depend on easydev. The full
165
+ module-by-module guide is in the
166
+ `documentation <https://easydev.readthedocs.io/en/latest/migration.html>`_
167
+ (``doc/source/migration.rst``). Main replacements:
168
+
169
+ ========================================= ======================================================
170
+ easydev Use instead
171
+ ========================================= ======================================================
172
+ ``CustomConfig``, ``AppDirs`` ``platformdirs``
173
+ ``DynamicConfigParser`` ``configparser``
174
+ ``AttrDict`` ``types.SimpleNamespace`` / ``dataclasses``
175
+ ``Logging`` ``logging`` (+ ``colorlog``)
176
+ ``Progress`` ``tqdm``
177
+ ``MultiProcessing`` ``concurrent.futures.ProcessPoolExecutor``
178
+ ``shellcmd``, ``execute`` ``subprocess.run``
179
+ ``mkdirs``, ``touch``, ``get_home`` ``pathlib`` / ``os.makedirs(exist_ok=True)``
180
+ ``cmd_exists`` ``shutil.which``
181
+ ``md5`` ``hashlib.file_digest`` (Python 3.11+)
182
+ ``browse`` ``webbrowser.open``
183
+ ``get_dependencies`` ``importlib.metadata.requires``
184
+ ``get_share_file`` ``importlib.resources.files``
185
+ ========================================= ======================================================
186
+
187
+ For example, replacing ``CustomConfig``::
188
+
189
+ # before
190
+ from easydev import CustomConfig
191
+ config_dir = CustomConfig("myapp").user_config_dir
192
+
193
+ # after
194
+ from pathlib import Path
195
+ from platformdirs import user_config_dir
196
+
197
+ config_dir = Path(user_config_dir("myapp"))
198
+ config_dir.mkdir(parents=True, exist_ok=True)
199
+
158
200
  Changelog
159
201
  ---------
160
202
 
161
203
  ========= ==========================================================================
162
204
  Version Description
163
205
  ========= ==========================================================================
206
+ 0.15.0 * fix ``is_mac`` (always returned False)
207
+ * ``assert_list_almost_equal`` now warns (FutureWarning) when called without
208
+ ``places``/``deltas`` (nothing is compared); raises ``ListMismatchError``
209
+ (both ValueError and AssertionError)
210
+ * add a migration guide (README and documentation) explaining how to
211
+ replace easydev tools with the standard library, platformdirs, etc.
212
+ * require Python >= 3.9
164
213
  0.13.3 * update pyproject with contribs from @s-t-e-v-e-n-k see PR37
165
214
  0.13.2 * replace mock with unittest.mock (fixes
166
215
  https://github.com/cokelaer/easydev/issues/20)
@@ -119,12 +119,60 @@ Multiprocessing::
119
119
  t.run()
120
120
  print(t.results)
121
121
 
122
+ Moving away from easydev
123
+ ------------------------
124
+
125
+ easydev dates from a time when Python lacked many small conveniences. Most of
126
+ its tools now have a standard-library or well-maintained third-party
127
+ replacement, and new projects should not depend on easydev. The full
128
+ module-by-module guide is in the
129
+ `documentation <https://easydev.readthedocs.io/en/latest/migration.html>`_
130
+ (``doc/source/migration.rst``). Main replacements:
131
+
132
+ ========================================= ======================================================
133
+ easydev Use instead
134
+ ========================================= ======================================================
135
+ ``CustomConfig``, ``AppDirs`` ``platformdirs``
136
+ ``DynamicConfigParser`` ``configparser``
137
+ ``AttrDict`` ``types.SimpleNamespace`` / ``dataclasses``
138
+ ``Logging`` ``logging`` (+ ``colorlog``)
139
+ ``Progress`` ``tqdm``
140
+ ``MultiProcessing`` ``concurrent.futures.ProcessPoolExecutor``
141
+ ``shellcmd``, ``execute`` ``subprocess.run``
142
+ ``mkdirs``, ``touch``, ``get_home`` ``pathlib`` / ``os.makedirs(exist_ok=True)``
143
+ ``cmd_exists`` ``shutil.which``
144
+ ``md5`` ``hashlib.file_digest`` (Python 3.11+)
145
+ ``browse`` ``webbrowser.open``
146
+ ``get_dependencies`` ``importlib.metadata.requires``
147
+ ``get_share_file`` ``importlib.resources.files``
148
+ ========================================= ======================================================
149
+
150
+ For example, replacing ``CustomConfig``::
151
+
152
+ # before
153
+ from easydev import CustomConfig
154
+ config_dir = CustomConfig("myapp").user_config_dir
155
+
156
+ # after
157
+ from pathlib import Path
158
+ from platformdirs import user_config_dir
159
+
160
+ config_dir = Path(user_config_dir("myapp"))
161
+ config_dir.mkdir(parents=True, exist_ok=True)
162
+
122
163
  Changelog
123
164
  ---------
124
165
 
125
166
  ========= ==========================================================================
126
167
  Version Description
127
168
  ========= ==========================================================================
169
+ 0.15.0 * fix ``is_mac`` (always returned False)
170
+ * ``assert_list_almost_equal`` now warns (FutureWarning) when called without
171
+ ``places``/``deltas`` (nothing is compared); raises ``ListMismatchError``
172
+ (both ValueError and AssertionError)
173
+ * add a migration guide (README and documentation) explaining how to
174
+ replace easydev tools with the standard library, platformdirs, etc.
175
+ * require Python >= 3.9
128
176
  0.13.3 * update pyproject with contribs from @s-t-e-v-e-n-k see PR37
129
177
  0.13.2 * replace mock with unittest.mock (fixes
130
178
  https://github.com/cokelaer/easydev/issues/20)
@@ -16,14 +16,22 @@
16
16
  # $:Id $
17
17
 
18
18
  import tempfile
19
+ import warnings
19
20
 
20
21
  __all__ = ["assert_list_almost_equal", "trysetattr", "TempFile"]
21
22
 
22
23
 
24
+ class ListMismatchError(ValueError, AssertionError):
25
+ """Raised by :func:`assert_list_almost_equal` (ValueError kept for backward compatibility)"""
26
+
27
+
23
28
  def assert_list_almost_equal(first, second, places=None, deltas=None):
24
29
  """Combined version nose.tools.assert_almost_equal and assert_list_equal
25
30
 
26
31
  This function checks that 2 lists contain identical items.
32
+ Without *places* or *deltas* nothing is compared and a FutureWarning is
33
+ issued. On mismatch, :class:`ListMismatchError` is raised (it derives from
34
+ both ValueError, for backward compatibility, and AssertionError).
27
35
  The equality between pair of items is checked with assert_almost_equal
28
36
  function, which means you can check for the places argument
29
37
 
@@ -44,7 +52,14 @@ def assert_list_almost_equal(first, second, places=None, deltas=None):
44
52
  if deltas:
45
53
  for x, y in zip(first, second):
46
54
  if abs(x - y) > deltas:
47
- raise ValueError
55
+ raise ListMismatchError("{} != {} within tolerance {}".format(x, y, deltas))
56
+ else:
57
+ warnings.warn(
58
+ "assert_list_almost_equal called without places or deltas: nothing is compared. "
59
+ "This will become a strict comparison in a future release.",
60
+ FutureWarning,
61
+ stacklevel=2,
62
+ )
48
63
 
49
64
 
50
65
  def trysetattr(this, attrname, value, possible):
@@ -64,7 +64,7 @@ def is_linux():
64
64
 
65
65
 
66
66
  def is_mac():
67
- if get_platform() == "Mac":
67
+ if get_platform() in ("Darwin", "Mac"):
68
68
  return True
69
69
  else:
70
70
  return False
@@ -33,7 +33,7 @@ __all__ = [
33
33
 
34
34
 
35
35
  def precision(data, digit=2):
36
- """Round values in a list keeping only N digits precision
36
+ """Truncate a value (not round) keeping only N digits precision
37
37
 
38
38
  ::
39
39
 
@@ -116,24 +116,26 @@ def shellcmd(cmd, show=False, verbose=False, ignore_errors=False):
116
116
  :param str cmd: the command to call
117
117
  :param bool show: print the command
118
118
  :param bool verbose: print the output
119
+ :param bool ignore_errors: do not raise when the command writes to stderr
119
120
 
120
- :return: the output as a string
121
+ :return: the output as bytes (stripped)
121
122
  """
122
123
  if show:
123
124
  print(cmd)
124
125
  try:
125
126
  ret = subprocess.Popen([cmd], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
126
127
 
127
- output = ret.stdout.read().strip()
128
- error = ret.stderr.read().strip()
129
- ret.wait()
128
+ output, error = ret.communicate()
129
+ output = output.strip()
130
+ error = error.strip()
130
131
 
132
+ # Legacy behaviour kept on purpose (many packages rely on it): any
133
+ # output on stderr is an error, the exit status is not checked.
131
134
  if len(error) > 0:
132
135
  if ignore_errors is False:
133
136
  raise Exception(error)
134
- else:
135
- if verbose is True:
136
- print("Errors/Warning" + str(error))
137
+ elif verbose is True:
138
+ print("Errors/Warning" + str(error))
137
139
 
138
140
  if verbose is True:
139
141
  print(output)
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
4
4
 
5
5
  [project]
6
6
  name = "easydev"
7
- version = "0.14.0"
7
+ version = "0.15.0"
8
8
  description = "Common utilities to ease development of Python packages"
9
9
  authors = [
10
10
  { "name" = "Thomas Cokelaer", "email" = "thomas.cokelaer@pasteur.fr" },
@@ -48,7 +48,7 @@ Documentation = "https://easydev.readthedocs.io"
48
48
 
49
49
 
50
50
  [tool.poetry.dependencies]
51
- python = "^3.8"
51
+ python = "^3.9"
52
52
  colorama = "^0.4.6"
53
53
  colorlog = "^6.8.2"
54
54
  pexpect = "^4.9.0"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes