easydev 0.13.2__tar.gz → 0.14.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 (53) hide show
  1. easydev-0.14.0/PKG-INFO +173 -0
  2. easydev-0.14.0/README.rst +136 -0
  3. {easydev-0.13.2 → easydev-0.14.0}/easydev/appdirs.py +0 -3
  4. {easydev-0.13.2 → easydev-0.14.0}/easydev/browser.py +6 -10
  5. {easydev-0.13.2 → easydev-0.14.0}/easydev/chunks.py +0 -6
  6. {easydev-0.13.2 → easydev-0.14.0}/easydev/codecs.py +1 -1
  7. {easydev-0.13.2 → easydev-0.14.0}/easydev/config_tools.py +6 -6
  8. {easydev-0.13.2 → easydev-0.14.0}/easydev/console.py +1 -1
  9. {easydev-0.13.2 → easydev-0.14.0}/easydev/copybutton.py +1 -1
  10. {easydev-0.13.2 → easydev-0.14.0}/easydev/decorators.py +5 -5
  11. {easydev-0.13.2 → easydev-0.14.0}/easydev/easytest.py +2 -2
  12. {easydev-0.13.2 → easydev-0.14.0}/easydev/logging_tools.py +0 -1
  13. {easydev-0.13.2 → easydev-0.14.0}/easydev/misc.py +3 -9
  14. {easydev-0.13.2 → easydev-0.14.0}/easydev/multicore.py +8 -7
  15. {easydev-0.13.2 → easydev-0.14.0}/easydev/paths.py +6 -7
  16. {easydev-0.13.2 → easydev-0.14.0}/easydev/platform.py +11 -19
  17. {easydev-0.13.2 → easydev-0.14.0}/easydev/sphinx_themes.py +1 -1
  18. {easydev-0.13.2 → easydev-0.14.0}/easydev/tools.py +3 -6
  19. {easydev-0.13.2 → easydev-0.14.0}/easydev/url.py +3 -6
  20. {easydev-0.13.2 → easydev-0.14.0}/pyproject.toml +10 -6
  21. easydev-0.13.2/PKG-INFO +0 -86
  22. easydev-0.13.2/README.rst +0 -53
  23. {easydev-0.13.2 → easydev-0.14.0}/COPYING +0 -0
  24. {easydev-0.13.2 → easydev-0.14.0}/easydev/__init__.py +0 -0
  25. {easydev-0.13.2 → easydev-0.14.0}/easydev/dependencies.py +0 -0
  26. {easydev-0.13.2 → easydev-0.14.0}/easydev/doc.py +0 -0
  27. {easydev-0.13.2 → easydev-0.14.0}/easydev/md5tools.py +0 -0
  28. {easydev-0.13.2 → easydev-0.14.0}/easydev/options.py +0 -0
  29. {easydev-0.13.2 → easydev-0.14.0}/easydev/profiler.py +0 -0
  30. {easydev-0.13.2 → easydev-0.14.0}/easydev/progressbar.py +0 -0
  31. {easydev-0.13.2 → easydev-0.14.0}/easydev/share/__init__.py +0 -0
  32. {easydev-0.13.2 → easydev-0.14.0}/easydev/share/copybutton.js +0 -0
  33. {easydev-0.13.2 → easydev-0.14.0}/easydev/share/themes/cno/google_footer.html +0 -0
  34. {easydev-0.13.2 → easydev-0.14.0}/easydev/share/themes/cno/google_head.html +0 -0
  35. {easydev-0.13.2 → easydev-0.14.0}/easydev/share/themes/cno/index.html +0 -0
  36. {easydev-0.13.2 → easydev-0.14.0}/easydev/share/themes/cno/indexsidebar.html +0 -0
  37. {easydev-0.13.2 → easydev-0.14.0}/easydev/share/themes/cno/layout.html +0 -0
  38. {easydev-0.13.2 → easydev-0.14.0}/easydev/share/themes/cno/static/bgfooter.png +0 -0
  39. {easydev-0.13.2 → easydev-0.14.0}/easydev/share/themes/cno/static/bgtop.png +0 -0
  40. {easydev-0.13.2 → easydev-0.14.0}/easydev/share/themes/cno/static/software.css_t +0 -0
  41. {easydev-0.13.2 → easydev-0.14.0}/easydev/share/themes/cno/static/warning.jpg +0 -0
  42. {easydev-0.13.2 → easydev-0.14.0}/easydev/share/themes/cno/theme.conf +0 -0
  43. {easydev-0.13.2 → easydev-0.14.0}/easydev/share/themes/standard/google_footer.html +0 -0
  44. {easydev-0.13.2 → easydev-0.14.0}/easydev/share/themes/standard/google_head.html +0 -0
  45. {easydev-0.13.2 → easydev-0.14.0}/easydev/share/themes/standard/index.html +0 -0
  46. {easydev-0.13.2 → easydev-0.14.0}/easydev/share/themes/standard/indexsidebar.html +0 -0
  47. {easydev-0.13.2 → easydev-0.14.0}/easydev/share/themes/standard/layout.html +0 -0
  48. {easydev-0.13.2 → easydev-0.14.0}/easydev/share/themes/standard/static/bgfooter.png +0 -0
  49. {easydev-0.13.2 → easydev-0.14.0}/easydev/share/themes/standard/static/bgtop.png +0 -0
  50. {easydev-0.13.2 → easydev-0.14.0}/easydev/share/themes/standard/static/software.css_t +0 -0
  51. {easydev-0.13.2 → easydev-0.14.0}/easydev/share/themes/standard/static/warning.jpg +0 -0
  52. {easydev-0.13.2 → easydev-0.14.0}/easydev/share/themes/standard/theme.conf +0 -0
  53. {easydev-0.13.2 → easydev-0.14.0}/easydev/timer.py +0 -0
@@ -0,0 +1,173 @@
1
+ Metadata-Version: 2.3
2
+ Name: easydev
3
+ Version: 0.14.0
4
+ Summary: Common utilities to ease development of Python packages
5
+ License: BSD-3-Clause
6
+ Keywords: config,decorators,development
7
+ Author: Thomas Cokelaer
8
+ Author-email: thomas.cokelaer@pasteur.fr
9
+ Requires-Python: >=3.8,<4.0
10
+ Classifier: Development Status :: 5 - Production/Stable
11
+ Classifier: Intended Audience :: Education
12
+ Classifier: Intended Audience :: End Users/Desktop
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: License :: OSI Approved :: BSD License
16
+ Classifier: Operating System :: POSIX :: Linux
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Programming Language :: Python :: 3.14
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
25
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
26
+ Requires-Dist: colorama (>=0.4.6,<0.5.0)
27
+ Requires-Dist: colorlog (>=6.8.2,<7.0.0)
28
+ Requires-Dist: line-profiler (>=5.0.0,<6.0.0)
29
+ Requires-Dist: pexpect (>=4.9.0,<5.0.0)
30
+ Requires-Dist: platformdirs (>=4.2.0,<5.0.0)
31
+ Project-URL: Documentation, https://easydev.readthedocs.io
32
+ Project-URL: Homepage, https://easydev.readthedocs.io
33
+ Project-URL: Issues, https://github.com/cokelaer/easydev/issues
34
+ Project-URL: Repository, https://github.com/cokelaer/easydev
35
+ Description-Content-Type: text/x-rst
36
+
37
+ easydev
38
+ ##########
39
+
40
+ .. image:: https://badge.fury.io/py/easydev.svg
41
+ :target: https://pypi.python.org/pypi/easydev
42
+
43
+ .. image:: https://github.com/cokelaer/easydev/actions/workflows/main.yml/badge.svg
44
+ :target: https://github.com/cokelaer/easydev/actions/workflows/main.yml
45
+
46
+ .. image:: https://coveralls.io/repos/cokelaer/easydev/badge.svg?branch=main
47
+ :target: https://coveralls.io/r/cokelaer/easydev?branch=main
48
+
49
+ .. image:: https://static.pepy.tech/personalized-badge/easydev?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads
50
+ :target: https://pepy.tech/projects/easydev
51
+
52
+ :documentation: http://easydev-python.readthedocs.io/en/latest/
53
+ :contributions: Please join https://github.com/cokelaer/easydev
54
+ :source: Please use https://github.com/cokelaer/easydev
55
+ :issues: Please use https://github.com/cokelaer/easydev/issues
56
+ :Python version supported: 3.9, 3.10, 3.11, 3.12, 3.13, 3.14
57
+
58
+ Overview
59
+ --------
60
+
61
+ The `easydev <http://pypi.python.org/pypi/easydev/>`_ package provides
62
+ miscellaneous utility functions and classes that are repeatedly useful during
63
+ the development of Python packages. The goal is to help developers speed up
64
+ their work by providing ready-to-use tools for common tasks such as parameter
65
+ validation, logging, progress bars, configuration files, multiprocessing, and
66
+ more.
67
+
68
+ It has been used as an incubator for other packages (e.g.,
69
+ `colormap <http://pypi.python.org/pypi/colormap>`_) and is used in projects
70
+ such as `bioservices <https://pypi.python.org/pypi/bioservices>`_,
71
+ `sequana <https://sequana.readthedocs.io>`_, and
72
+ `GDSCTools <https://gdsctools.readthedocs.io>`_.
73
+
74
+ Installation
75
+ ------------
76
+
77
+ Install the latest release from PyPI::
78
+
79
+ pip install easydev
80
+
81
+ Features
82
+ --------
83
+
84
+ - **Parameter validation** – ``check_param_in_list``, ``check_range``
85
+ - **Dictionary utilities** – ``swapdict``, ``AttrDict`` (access dict keys as attributes, supports nested dicts)
86
+ - **Logging** – coloured logging via ``Logging`` class
87
+ - **Progress bar** – ``Progress`` works in Python, IPython, and Jupyter notebooks
88
+ - **Timer** – measure elapsed time with the ``Timer`` context manager
89
+ - **Profiling** – ``do_profile`` decorator using ``line_profiler``
90
+ - **Configuration files** – ``CustomConfig`` and ``DynamicConfigParser`` for INI-style config management
91
+ - **Shell commands** – ``shellcmd`` and ``execute`` wrappers around subprocess/pexpect
92
+ - **File utilities** – ``touch``, ``mkdirs``, ``md5``
93
+ - **Multiprocessing** – ``MultiProcessing`` class for easy parallel job execution
94
+ - **Codecs** – ``to_list``, ``list2string`` and other conversion helpers
95
+ - **URL utilities** – ``isurl_reachable`` and related helpers
96
+ - **Sphinx integration** – bundled Sphinx theme and ``copybutton`` extension
97
+
98
+ Quick Start
99
+ -----------
100
+
101
+ Parameter validation::
102
+
103
+ from easydev import check_param_in_list, check_range
104
+
105
+ check_param_in_list("on", ["on", "off"]) # passes silently
106
+ check_range(0.5, 0, 1) # passes silently
107
+
108
+ AttrDict – access nested dictionary keys as attributes::
109
+
110
+ from easydev import AttrDict
111
+
112
+ d = AttrDict(**{"server": {"host": "localhost", "port": 8080}})
113
+ print(d.server.host) # localhost
114
+ d.server.port = 9090
115
+
116
+ Coloured logging::
117
+
118
+ from easydev import Logging
119
+
120
+ logger = Logging("myapp", "WARNING")
121
+ logger.warning("something went wrong")
122
+ logger.debug("not shown at WARNING level")
123
+ logger.level = "DEBUG"
124
+ logger.debug("now it is shown")
125
+
126
+ Progress bar::
127
+
128
+ from easydev import Progress
129
+
130
+ pb = Progress(100)
131
+ for i in range(100):
132
+ # do work here
133
+ pb.animate(i + 1)
134
+
135
+ Timer::
136
+
137
+ from easydev import Timer
138
+ import time
139
+
140
+ times = []
141
+ with Timer(times):
142
+ time.sleep(0.1)
143
+ print(f"elapsed: {times[0]:.2f}s")
144
+
145
+ Multiprocessing::
146
+
147
+ from easydev.multicore import MultiProcessing
148
+
149
+ def square(n):
150
+ return n * n
151
+
152
+ t = MultiProcessing(maxcpu=4)
153
+ for i in range(10):
154
+ t.add_job(square, i)
155
+ t.run()
156
+ print(t.results)
157
+
158
+ Changelog
159
+ ---------
160
+
161
+ ========= ==========================================================================
162
+ Version Description
163
+ ========= ==========================================================================
164
+ 0.13.3 * update pyproject with contribs from @s-t-e-v-e-n-k see PR37
165
+ 0.13.2 * replace mock with unittest.mock (fixes
166
+ https://github.com/cokelaer/easydev/issues/20)
167
+ 0.13.1 * fix get_dependencies
168
+ 0.13.0 * fix requirements (line_profiler) and CI
169
+ 0.12.2 * For developers: move to pyproject. add precommit
170
+ * replace pkg_resources (deprecated) with importlib
171
+ * replace appdirs with more generic platformdirs
172
+ ========= ==========================================================================
173
+
@@ -0,0 +1,136 @@
1
+ easydev
2
+ ##########
3
+
4
+ .. image:: https://badge.fury.io/py/easydev.svg
5
+ :target: https://pypi.python.org/pypi/easydev
6
+
7
+ .. image:: https://github.com/cokelaer/easydev/actions/workflows/main.yml/badge.svg
8
+ :target: https://github.com/cokelaer/easydev/actions/workflows/main.yml
9
+
10
+ .. image:: https://coveralls.io/repos/cokelaer/easydev/badge.svg?branch=main
11
+ :target: https://coveralls.io/r/cokelaer/easydev?branch=main
12
+
13
+ .. image:: https://static.pepy.tech/personalized-badge/easydev?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads
14
+ :target: https://pepy.tech/projects/easydev
15
+
16
+ :documentation: http://easydev-python.readthedocs.io/en/latest/
17
+ :contributions: Please join https://github.com/cokelaer/easydev
18
+ :source: Please use https://github.com/cokelaer/easydev
19
+ :issues: Please use https://github.com/cokelaer/easydev/issues
20
+ :Python version supported: 3.9, 3.10, 3.11, 3.12, 3.13, 3.14
21
+
22
+ Overview
23
+ --------
24
+
25
+ The `easydev <http://pypi.python.org/pypi/easydev/>`_ package provides
26
+ miscellaneous utility functions and classes that are repeatedly useful during
27
+ the development of Python packages. The goal is to help developers speed up
28
+ their work by providing ready-to-use tools for common tasks such as parameter
29
+ validation, logging, progress bars, configuration files, multiprocessing, and
30
+ more.
31
+
32
+ It has been used as an incubator for other packages (e.g.,
33
+ `colormap <http://pypi.python.org/pypi/colormap>`_) and is used in projects
34
+ such as `bioservices <https://pypi.python.org/pypi/bioservices>`_,
35
+ `sequana <https://sequana.readthedocs.io>`_, and
36
+ `GDSCTools <https://gdsctools.readthedocs.io>`_.
37
+
38
+ Installation
39
+ ------------
40
+
41
+ Install the latest release from PyPI::
42
+
43
+ pip install easydev
44
+
45
+ Features
46
+ --------
47
+
48
+ - **Parameter validation** – ``check_param_in_list``, ``check_range``
49
+ - **Dictionary utilities** – ``swapdict``, ``AttrDict`` (access dict keys as attributes, supports nested dicts)
50
+ - **Logging** – coloured logging via ``Logging`` class
51
+ - **Progress bar** – ``Progress`` works in Python, IPython, and Jupyter notebooks
52
+ - **Timer** – measure elapsed time with the ``Timer`` context manager
53
+ - **Profiling** – ``do_profile`` decorator using ``line_profiler``
54
+ - **Configuration files** – ``CustomConfig`` and ``DynamicConfigParser`` for INI-style config management
55
+ - **Shell commands** – ``shellcmd`` and ``execute`` wrappers around subprocess/pexpect
56
+ - **File utilities** – ``touch``, ``mkdirs``, ``md5``
57
+ - **Multiprocessing** – ``MultiProcessing`` class for easy parallel job execution
58
+ - **Codecs** – ``to_list``, ``list2string`` and other conversion helpers
59
+ - **URL utilities** – ``isurl_reachable`` and related helpers
60
+ - **Sphinx integration** – bundled Sphinx theme and ``copybutton`` extension
61
+
62
+ Quick Start
63
+ -----------
64
+
65
+ Parameter validation::
66
+
67
+ from easydev import check_param_in_list, check_range
68
+
69
+ check_param_in_list("on", ["on", "off"]) # passes silently
70
+ check_range(0.5, 0, 1) # passes silently
71
+
72
+ AttrDict – access nested dictionary keys as attributes::
73
+
74
+ from easydev import AttrDict
75
+
76
+ d = AttrDict(**{"server": {"host": "localhost", "port": 8080}})
77
+ print(d.server.host) # localhost
78
+ d.server.port = 9090
79
+
80
+ Coloured logging::
81
+
82
+ from easydev import Logging
83
+
84
+ logger = Logging("myapp", "WARNING")
85
+ logger.warning("something went wrong")
86
+ logger.debug("not shown at WARNING level")
87
+ logger.level = "DEBUG"
88
+ logger.debug("now it is shown")
89
+
90
+ Progress bar::
91
+
92
+ from easydev import Progress
93
+
94
+ pb = Progress(100)
95
+ for i in range(100):
96
+ # do work here
97
+ pb.animate(i + 1)
98
+
99
+ Timer::
100
+
101
+ from easydev import Timer
102
+ import time
103
+
104
+ times = []
105
+ with Timer(times):
106
+ time.sleep(0.1)
107
+ print(f"elapsed: {times[0]:.2f}s")
108
+
109
+ Multiprocessing::
110
+
111
+ from easydev.multicore import MultiProcessing
112
+
113
+ def square(n):
114
+ return n * n
115
+
116
+ t = MultiProcessing(maxcpu=4)
117
+ for i in range(10):
118
+ t.add_job(square, i)
119
+ t.run()
120
+ print(t.results)
121
+
122
+ Changelog
123
+ ---------
124
+
125
+ ========= ==========================================================================
126
+ Version Description
127
+ ========= ==========================================================================
128
+ 0.13.3 * update pyproject with contribs from @s-t-e-v-e-n-k see PR37
129
+ 0.13.2 * replace mock with unittest.mock (fixes
130
+ https://github.com/cokelaer/easydev/issues/20)
131
+ 0.13.1 * fix get_dependencies
132
+ 0.13.0 * fix requirements (line_profiler) and CI
133
+ 0.12.2 * For developers: move to pyproject. add precommit
134
+ * replace pkg_resources (deprecated) with importlib
135
+ * replace appdirs with more generic platformdirs
136
+ ========= ==========================================================================
@@ -1,6 +1,3 @@
1
- import os
2
- import sys
3
-
4
1
  from platformdirs import (
5
2
  site_config_dir,
6
3
  site_data_dir,
@@ -61,11 +61,9 @@ There is also an alias **onweb**::
61
61
  from easydev import onweb
62
62
 
63
63
  """
64
- import argparse
65
64
  import os
66
65
  import sys
67
66
  import webbrowser
68
- from optparse import OptionParser
69
67
 
70
68
 
71
69
  def browse(url, verbose=True):
@@ -93,23 +91,23 @@ def _browse_mac(url, verbose=True): # pragma: no cover
93
91
  try:
94
92
  os.system("open /Applications/Safari.app {}".format(url))
95
93
  return
96
- except:
94
+ except Exception:
97
95
  pass
98
96
 
99
97
  try:
100
98
  os.system("open /Applications/Safari.app {}".format("http://" + url))
101
99
  return
102
- except:
100
+ except Exception:
103
101
  pass
104
102
 
105
103
  try:
106
104
  webbrowser.open_new(url)
107
- except:
105
+ except Exception:
108
106
  if verbose:
109
107
  print("Could not open %s. Trying to append http://" % url)
110
108
  try:
111
109
  webbrowser.open_new("open http://{}".format(url))
112
- except:
110
+ except Exception:
113
111
  print("Could not open http://%s" % url)
114
112
  raise Exception
115
113
 
@@ -120,7 +118,7 @@ def _browse_linux(url, verbose=True): # pragma: no cover
120
118
  try:
121
119
  webbrowser.open(url)
122
120
  return
123
- except:
121
+ except Exception:
124
122
  pass
125
123
 
126
124
  try:
@@ -128,7 +126,7 @@ def _browse_linux(url, verbose=True): # pragma: no cover
128
126
  print("Could not open %s" % url)
129
127
  webbrowser.open("http://" + url)
130
128
  return
131
- except:
129
+ except Exception:
132
130
  pass
133
131
 
134
132
  raise Exception("Could not open http://{}".format(url))
@@ -172,6 +170,4 @@ def main(args=None): # pragma: no cover
172
170
 
173
171
 
174
172
  if __name__ == "__main__": # pragma: no cover
175
- import sys
176
-
177
173
  main(sys.argv)
@@ -29,12 +29,6 @@
29
29
  __all__ = ["split_into_chunks"]
30
30
 
31
31
 
32
- try:
33
- range = xrange # py2
34
- except:
35
- pass # py3
36
-
37
-
38
32
  def split_into_chunks(items, maxchunks=10):
39
33
  """Split a list evenly into N chunks
40
34
 
@@ -56,7 +56,7 @@ def to_list(data, verbose=True):
56
56
  try:
57
57
  data = data.tolist()
58
58
  return data
59
- except:
59
+ except Exception:
60
60
  if verbose:
61
61
  print("not known type. Trying to cast into a list")
62
62
  return list(data)
@@ -125,14 +125,14 @@ class DynamicConfigParser(ConfigParser):
125
125
  self.read(self._filename)
126
126
  elif isinstance(config_or_filename, ConfigParser):
127
127
  self._replace_config(config_or_filename)
128
- elif config_or_filename == None:
128
+ elif config_or_filename is None:
129
129
  pass
130
130
  else:
131
131
  raise TypeError("config_or_filename must be a valid filename or valid ConfigParser instance")
132
132
 
133
133
  def read(self, filename):
134
134
  """Load a new config from a filename (remove all previous sections)"""
135
- if os.path.isfile(filename) == False:
135
+ if not os.path.isfile(filename):
136
136
  raise IOError("filename {0} not found".format(filename))
137
137
 
138
138
  config = ConfigParser()
@@ -220,9 +220,9 @@ class DynamicConfigParser(ConfigParser):
220
220
  try: # numbers
221
221
  try:
222
222
  options[option] = self.getint(section, option)
223
- except:
223
+ except Exception:
224
224
  options[option] = self.getfloat(section, option)
225
- except: # string
225
+ except Exception: # string
226
226
  options[option] = self.get(section, option, raw=True)
227
227
  return options
228
228
 
@@ -238,7 +238,7 @@ class DynamicConfigParser(ConfigParser):
238
238
 
239
239
  """
240
240
  try:
241
- if os.path.exists(filename) == True:
241
+ if os.path.exists(filename):
242
242
  print("Warning: over-writing %s " % filename)
243
243
  fp = open(filename, "w")
244
244
  except Exception as err: # pragma: no cover
@@ -311,7 +311,7 @@ class DynamicConfigParser(ConfigParser):
311
311
  if str(self.get(section, option, raw=True)) != str(data.get(section, option, raw=True)):
312
312
  print("option %s in section %s differ" % (option, section))
313
313
  return False
314
- except: # pragma: no cover
314
+ except Exception: # pragma: no cover
315
315
  return False
316
316
  return True
317
317
 
@@ -48,7 +48,7 @@ def get_terminal_width():
48
48
  terminal_width = width
49
49
  except (SystemExit, KeyboardInterrupt): # pragma: no cover
50
50
  raise
51
- except:
51
+ except Exception:
52
52
  # FALLBACK
53
53
  terminal_width = int(os.environ.get("COLUMNS", 80)) - 1
54
54
  return terminal_width
@@ -91,7 +91,7 @@ def get_copybutton_path():
91
91
  try:
92
92
  packagedir = easydev.__path__[0]
93
93
  packagedir = os.path.realpath(pj(packagedir, "..", "share"))
94
- except:
94
+ except Exception:
95
95
  raise IOError("could not find data directory")
96
96
  return pj(packagedir, "copybutton.js")
97
97
 
@@ -14,7 +14,6 @@
14
14
  #
15
15
  ##############################################################################
16
16
  """Handy decorators"""
17
- import threading
18
17
  from functools import wraps
19
18
 
20
19
  __all__ = ["ifpylab", "requires", "ifpandas"]
@@ -100,6 +99,7 @@ def _blocking(not_avail):
100
99
  return blocking
101
100
  """
102
101
 
102
+
103
103
  # same as require decorator but works with list of stirngs of
104
104
  # single string and uses the functools utilities
105
105
  def requires(requires, msg=""):
@@ -122,7 +122,7 @@ def requires(requires, msg=""):
122
122
  """
123
123
  if isinstance(requires, str):
124
124
  requires = [requires]
125
- elif isinstance(requires, list) == False:
125
+ elif not isinstance(requires, list):
126
126
  raise TypeError(
127
127
  "First argument of the /requires/ decorator must be a"
128
128
  + "string or list of string representing the required attributes"
@@ -134,7 +134,7 @@ def requires(requires, msg=""):
134
134
  @wraps(f)
135
135
  def wrapper(*args, **kwds):
136
136
  for require in requires:
137
- if hasattr(args[0], require) == False:
137
+ if not hasattr(args[0], require):
138
138
  raise AttributeError("{} not found in {}. ".format(require, args[0]) + msg)
139
139
  return f(*args, **kwds)
140
140
 
@@ -157,7 +157,7 @@ def ifpandas(func):
157
157
  return func(*args, **kwds)
158
158
 
159
159
  try:
160
- import pandas
160
+ import pandas # noqa: F401
161
161
 
162
162
  return wrapper
163
163
  except Exception: # pragma: no cover
@@ -179,7 +179,7 @@ def ifpylab(func):
179
179
 
180
180
  # for methods
181
181
  try:
182
- import pylab
182
+ import pylab # noqa: F401
183
183
 
184
184
  return wrapper
185
185
  except Exception: # pragma: no cover
@@ -71,7 +71,7 @@ def trysetattr(this, attrname, value, possible):
71
71
  AssertionError
72
72
 
73
73
  """
74
- if possible == True:
74
+ if possible is True:
75
75
  a1 = True
76
76
  a2 = False
77
77
  else:
@@ -102,7 +102,7 @@ class TempFile(object):
102
102
  def delete(self):
103
103
  try:
104
104
  self.temp._closer.delete = True
105
- except: # pragma: no cover
105
+ except AttributeError: # pragma: no cover
106
106
  self.temp.delete = True
107
107
  self.temp.close()
108
108
 
@@ -59,7 +59,6 @@ class Logging(object):
59
59
  def _set_name(self, name):
60
60
  level = self.level
61
61
  self._name = name
62
- logger = colorlog.getLogger(self._name)
63
62
  if level == 0:
64
63
  self._set_level("WARNING")
65
64
  else:
@@ -20,16 +20,10 @@ __all__ = ["get_home", "cmd_exists"]
20
20
 
21
21
  def get_home():
22
22
  """Return path of the HOME"""
23
- # This function should be robust
24
23
  # First, let us try with expanduser
25
- try:
26
- homedir = os.path.expanduser("~")
27
- except ImportError: # pragma: no cover
28
- # This may happen.
29
- pass
30
- else:
31
- if os.path.isdir(homedir):
32
- return homedir
24
+ homedir = os.path.expanduser("~")
25
+ if os.path.isdir(homedir):
26
+ return homedir
33
27
  # Then, with getenv
34
28
  for this in ("HOME", "USERPROFILE", "TMP"): # pragma: no cover
35
29
  # getenv is same as os.environ.get
@@ -19,6 +19,12 @@ from multiprocessing import Pool, Process, Queue, cpu_count
19
19
  __all__ = ["MultiProcessing"]
20
20
 
21
21
 
22
+ def _init_worker():
23
+ import signal
24
+
25
+ signal.signal(signal.SIGINT, signal.SIG_IGN)
26
+
27
+
22
28
  class MultiProcessing(object):
23
29
  """Class to run jobs in an asynchronous manner.
24
30
 
@@ -53,7 +59,7 @@ class MultiProcessing(object):
53
59
 
54
60
 
55
61
  """
56
- if maxcpu == None:
62
+ if maxcpu is None:
57
63
  maxcpu = cpu_count()
58
64
 
59
65
  self.maxcpu = maxcpu
@@ -102,13 +108,8 @@ class MultiProcessing(object):
102
108
  self.pb = Progress(len(self.jobs), 1)
103
109
  self.pb.animate(0)
104
110
 
105
- def init_worker():
106
- import signal
107
-
108
- signal.signal(signal.SIGINT, signal.SIG_IGN)
109
-
110
111
  self.results = []
111
- self.pool = Pool(self.maxcpu, init_worker)
112
+ self.pool = Pool(self.maxcpu, _init_worker)
112
113
 
113
114
  for process in self.jobs:
114
115
  self.pool.apply_async(process._target, process._args, process._kwargs, callback=self._cb)
@@ -18,7 +18,6 @@
18
18
  import importlib
19
19
  import os
20
20
  from os.path import join as pj
21
- from pathlib import Path
22
21
 
23
22
  __all__ = [
24
23
  "get_shared_directory_path",
@@ -53,7 +52,7 @@ def get_shared_directory_path(package):
53
52
 
54
53
  # print("install mode ? ")
55
54
  sharedir = os.path.realpath(pj(location, package, "share"))
56
- if os.path.isdir(sharedir) == True:
55
+ if os.path.isdir(sharedir):
57
56
  # looks like we have found the share directory so it is an install mode
58
57
  # print ("yes")
59
58
  return sharedir
@@ -63,13 +62,13 @@ def get_shared_directory_path(package):
63
62
  # FIXME: do we need the 3 cases ??
64
63
  # probably just 2 are required, one for develop and one for install mode
65
64
  sharedir = os.path.realpath(pj(location, "..", "share"))
66
- if os.path.isdir(sharedir) == True:
65
+ if os.path.isdir(sharedir):
67
66
  return sharedir
68
67
  sharedir = os.path.realpath(pj(location, "..", "..", "share"))
69
- if os.path.isdir(sharedir) == True:
68
+ if os.path.isdir(sharedir):
70
69
  return sharedir
71
70
  sharedir = os.path.realpath(pj(location, "..", "..", "..", "share"))
72
- if os.path.isdir(sharedir) == True:
71
+ if os.path.isdir(sharedir):
73
72
  return sharedir
74
73
  # could not be found,
75
74
  sharedir = []
@@ -117,10 +116,10 @@ def get_share_file(package, datadir, filename):
117
116
  packagedir = get_shared_directory_path(package)
118
117
  fullpath = os.path.join(packagedir, datadir)
119
118
  # check that it exists
120
- if os.path.isdir(fullpath) == False: # pragma: no cover
119
+ if not os.path.isdir(fullpath): # pragma: no cover
121
120
  raise ValueError("The directory %s in package %s does not seem to exist" % (packagedir, fullpath))
122
121
  filename_path = os.path.join(fullpath, filename)
123
- if os.path.isfile(filename_path) == False:
122
+ if not os.path.isfile(filename_path):
124
123
  correct_files = [x for x in os.listdir(fullpath) if os.path.isfile(x)]
125
124
  msg = "The file %s does not exists. Correct filenames found in %s/%s are:\n" % (
126
125
  filename_path,
@@ -14,7 +14,6 @@
14
14
  #
15
15
  ##############################################################################
16
16
 
17
- import os
18
17
  import sys
19
18
 
20
19
  __all__ = ["get_platform"]
@@ -36,24 +35,17 @@ def get_platform(): # pragma: no cover
36
35
 
37
36
  """
38
37
  print("//easydev.get_platform() Will be deprecated in future version of easydev")
39
- try:
40
- platform = plf.system()
41
- return platform
42
- except:
43
- # platform is not available under all systems (e.g., WLST tool
44
- # see http://stackoverflow.com/questions/1854/python-what-os-am-i-running-on
45
- # so, let us try sys.platform
46
- platform = sys.platform
47
- if platform.startswith("linux"):
48
- platform = "Linux"
49
- elif platform.startswith("java"):
50
- platform = "Java"
51
- elif platform.startswith("win"):
52
- platform = "Windows"
53
- elif platform.startswith("darwin"):
54
- platform = "Darwin"
55
- else:
56
- print("platform not parsed. Return raw value of sys.platform.")
38
+ platform = sys.platform
39
+ if platform.startswith("linux"):
40
+ platform = "Linux"
41
+ elif platform.startswith("java"):
42
+ platform = "Java"
43
+ elif platform.startswith("win"):
44
+ platform = "Windows"
45
+ elif platform.startswith("darwin"):
46
+ platform = "Darwin"
47
+ else:
48
+ print("platform not parsed. Return raw value of sys.platform.")
57
49
  return platform
58
50
 
59
51
 
@@ -51,5 +51,5 @@ def get_sphinx_themes():
51
51
 
52
52
  sharedir = get_shared_directory_path("easydev")
53
53
  sharedir = pj(sharedir, "themes")
54
- themes = [x for x in os.listdir(sharedir) if x.startswith(".") == False]
54
+ themes = [x for x in os.listdir(sharedir) if not x.startswith(".")]
55
55
  return themes
@@ -161,7 +161,7 @@ def execute(cmd, showcmd=True, verbose=True):
161
161
  if verbose:
162
162
  try:
163
163
  sys.stdout.write(line.decode())
164
- except:
164
+ except Exception:
165
165
  sys.stdout.write(line)
166
166
 
167
167
  sys.stdout.flush()
@@ -279,12 +279,9 @@ class AttrDict(dict):
279
279
 
280
280
  :param dict content: a valid dictionary
281
281
  """
282
- # accepts dict and attrdict classes
283
- try:
284
- from collections import OrderedDict
285
- except:
286
- OrderedDict = AttrDict
282
+ from collections import OrderedDict
287
283
 
284
+ # accepts dict and attrdict classes
288
285
  if content.__class__ not in [dict, OrderedDict, AttrDict]:
289
286
  raise TypeError
290
287
 
@@ -14,10 +14,7 @@
14
14
  #
15
15
  ##############################################################################
16
16
  """Utilities related to the web"""
17
- try:
18
- import httplib
19
- except ImportError:
20
- import http.client as httplib
17
+ import http.client as httplib
21
18
 
22
19
  __all__ = ["isurl_reachable"]
23
20
 
@@ -39,13 +36,13 @@ def isurl_reachable(url, timeout=10, path="/"): # pragma: no cover
39
36
  conn = httplib.HTTPConnection(url, timeout=timeout)
40
37
  try:
41
38
  conn.request("HEAD", path)
42
- except:
39
+ except Exception:
43
40
  return False
44
41
  # 302 is a redirection
45
42
  # 200 is okay
46
43
  try:
47
44
  response = conn.getresponse()
48
- except:
45
+ except Exception:
49
46
  return False
50
47
 
51
48
  if response.status in [200, 302]:
@@ -2,11 +2,13 @@
2
2
  requires = ["poetry-core"]
3
3
  build-backend = "poetry.core.masonry.api"
4
4
 
5
- [tool.poetry]
5
+ [project]
6
6
  name = "easydev"
7
- version = "0.13.2"
8
- description = "Commn utilities to ease development of Python packages"
9
- authors = ["Thomas Cokelaer <thomas.cokelaer@pasteur.fr>"]
7
+ version = "0.14.0"
8
+ description = "Common utilities to ease development of Python packages"
9
+ authors = [
10
+ { "name" = "Thomas Cokelaer", "email" = "thomas.cokelaer@pasteur.fr" },
11
+ ]
10
12
  license = "BSD-3-Clause"
11
13
  readme = "README.rst"
12
14
  keywords = ["config", "decorators", "development"]
@@ -19,10 +21,12 @@ classifiers = [
19
21
  "Intended Audience :: Science/Research",
20
22
  "License :: OSI Approved :: BSD License",
21
23
  "Operating System :: POSIX :: Linux",
22
- "Programming Language :: Python :: 3.8",
23
24
  "Programming Language :: Python :: 3.9",
24
25
  "Programming Language :: Python :: 3.10",
25
26
  "Programming Language :: Python :: 3.11",
27
+ "Programming Language :: Python :: 3.12",
28
+ "Programming Language :: Python :: 3.13",
29
+ "Programming Language :: Python :: 3.14",
26
30
  "Topic :: Software Development :: Libraries :: Python Modules",
27
31
  "Topic :: Scientific/Engineering :: Bio-Informatics",
28
32
  "Topic :: Scientific/Engineering :: Information Analysis",
@@ -49,7 +53,7 @@ colorama = "^0.4.6"
49
53
  colorlog = "^6.8.2"
50
54
  pexpect = "^4.9.0"
51
55
  platformdirs = "^4.2.0"
52
- line-profiler = "^4.1.2"
56
+ line-profiler = "^5.0.0"
53
57
 
54
58
 
55
59
 
easydev-0.13.2/PKG-INFO DELETED
@@ -1,86 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: easydev
3
- Version: 0.13.2
4
- Summary: Commn utilities to ease development of Python packages
5
- License: BSD-3-Clause
6
- Keywords: config,decorators,development
7
- Author: Thomas Cokelaer
8
- Author-email: thomas.cokelaer@pasteur.fr
9
- Requires-Python: >=3.8,<4.0
10
- Classifier: Development Status :: 5 - Production/Stable
11
- Classifier: Intended Audience :: Developers
12
- Classifier: Intended Audience :: Education
13
- Classifier: Intended Audience :: End Users/Desktop
14
- Classifier: Intended Audience :: Science/Research
15
- Classifier: License :: OSI Approved :: BSD License
16
- Classifier: Operating System :: POSIX :: Linux
17
- Classifier: Programming Language :: Python :: 3
18
- Classifier: Programming Language :: Python :: 3.8
19
- Classifier: Programming Language :: Python :: 3.9
20
- Classifier: Programming Language :: Python :: 3.10
21
- Classifier: Programming Language :: Python :: 3.11
22
- Classifier: Programming Language :: Python :: 3.12
23
- Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
24
- Classifier: Topic :: Scientific/Engineering :: Information Analysis
25
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
26
- Requires-Dist: colorama (>=0.4.6,<0.5.0)
27
- Requires-Dist: colorlog (>=6.8.2,<7.0.0)
28
- Requires-Dist: line-profiler (>=4.1.2,<5.0.0)
29
- Requires-Dist: pexpect (>=4.9.0,<5.0.0)
30
- Requires-Dist: platformdirs (>=4.2.0,<5.0.0)
31
- Description-Content-Type: text/x-rst
32
-
33
- easydev
34
- ##########
35
-
36
- .. image:: https://badge.fury.io/py/easydev.svg
37
- :target: https://pypi.python.org/pypi/easydev
38
-
39
- .. image:: https://github.com/cokelaer/easydev/actions/workflows/main.yml/badge.svg
40
- :target: https://github.com/cokelaer/easydev/actions/workflows/main.yml
41
-
42
-
43
- .. image:: https://coveralls.io/repos/cokelaer/easydev/badge.svg?branch=main
44
- :target: https://coveralls.io/r/cokelaer/easydev?branch=main
45
-
46
-
47
-
48
-
49
- :documentation: http://easydev-python.readthedocs.io/en/latest/
50
- :contributions: Please join https://github.com/cokelaer/easydev
51
- :source: Please use https://github.com/cokelaer/easydev
52
- :issues: Please use https://github.com/cokelaer/easydev/issues
53
- :Python version supported: 3.7, 3.8, 3.9, 3.10, 3.11, 3.12
54
-
55
-
56
- The `easydev <http://pypi.python.org/pypi/easydev/>`_ package
57
- provides miscellaneous functions that are repeatidly used during
58
- the development of Python packages. The goal is to help developers on
59
- speeding up their own dev. It has been used also as an incubator for other
60
- packages (e.g., http://pypi.python.org/pypi/colormap) and is stable.
61
-
62
- .. warning:: I'm not pretending to provide universal and bug-free tools. The
63
- tools provided may also change. However, **easydev** is used
64
- in a few other packages such as
65
- `bioservices <https://pypi.python.org/pypi/bioservices>`_,
66
- `sequana <https://sequana.readthedocs.io>`_ or
67
- `GDSCTools <https://sequana.readthedocs.io>`_ to give a few
68
- examples.
69
-
70
-
71
-
72
- Changelog
73
- ~~~~~~~~~
74
-
75
- ========= ==========================================================================
76
- Version Description
77
- ========= ==========================================================================
78
- 0.13.2 * replace mock with unittest.mock (fixes
79
- https://github.com/cokelaer/easydev/issues/20)
80
- 0.13.1 * fix get_dependencies
81
- 0.13.0 * fix requirements (line_profiler) and CI
82
- 0.12.2 * For developers: move to pyprojet. add precomit
83
- * replace pkg_resources (deprecated) with importlib
84
- * replace appdirs with more generic platformdirs
85
- ========= ==========================================================================
86
-
easydev-0.13.2/README.rst DELETED
@@ -1,53 +0,0 @@
1
- easydev
2
- ##########
3
-
4
- .. image:: https://badge.fury.io/py/easydev.svg
5
- :target: https://pypi.python.org/pypi/easydev
6
-
7
- .. image:: https://github.com/cokelaer/easydev/actions/workflows/main.yml/badge.svg
8
- :target: https://github.com/cokelaer/easydev/actions/workflows/main.yml
9
-
10
-
11
- .. image:: https://coveralls.io/repos/cokelaer/easydev/badge.svg?branch=main
12
- :target: https://coveralls.io/r/cokelaer/easydev?branch=main
13
-
14
-
15
-
16
-
17
- :documentation: http://easydev-python.readthedocs.io/en/latest/
18
- :contributions: Please join https://github.com/cokelaer/easydev
19
- :source: Please use https://github.com/cokelaer/easydev
20
- :issues: Please use https://github.com/cokelaer/easydev/issues
21
- :Python version supported: 3.7, 3.8, 3.9, 3.10, 3.11, 3.12
22
-
23
-
24
- The `easydev <http://pypi.python.org/pypi/easydev/>`_ package
25
- provides miscellaneous functions that are repeatidly used during
26
- the development of Python packages. The goal is to help developers on
27
- speeding up their own dev. It has been used also as an incubator for other
28
- packages (e.g., http://pypi.python.org/pypi/colormap) and is stable.
29
-
30
- .. warning:: I'm not pretending to provide universal and bug-free tools. The
31
- tools provided may also change. However, **easydev** is used
32
- in a few other packages such as
33
- `bioservices <https://pypi.python.org/pypi/bioservices>`_,
34
- `sequana <https://sequana.readthedocs.io>`_ or
35
- `GDSCTools <https://sequana.readthedocs.io>`_ to give a few
36
- examples.
37
-
38
-
39
-
40
- Changelog
41
- ~~~~~~~~~
42
-
43
- ========= ==========================================================================
44
- Version Description
45
- ========= ==========================================================================
46
- 0.13.2 * replace mock with unittest.mock (fixes
47
- https://github.com/cokelaer/easydev/issues/20)
48
- 0.13.1 * fix get_dependencies
49
- 0.13.0 * fix requirements (line_profiler) and CI
50
- 0.12.2 * For developers: move to pyprojet. add precomit
51
- * replace pkg_resources (deprecated) with importlib
52
- * replace appdirs with more generic platformdirs
53
- ========= ==========================================================================
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes