sferriol-python 0.4.1__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.
@@ -0,0 +1,24 @@
1
+ This is free and unencumbered software released into the public domain.
2
+
3
+ Anyone is free to copy, modify, publish, use, compile, sell, or
4
+ distribute this software, either in source code form or as a compiled
5
+ binary, for any purpose, commercial or non-commercial, and by any
6
+ means.
7
+
8
+ In jurisdictions that recognize copyright laws, the author or authors
9
+ of this software dedicate any and all copyright interest in the
10
+ software to the public domain. We make this dedication for the benefit
11
+ of the public at large and to the detriment of our heirs and
12
+ successors. We intend this dedication to be an overt act of
13
+ relinquishment in perpetuity of all present and future rights to this
14
+ software under copyright law.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ For more information, please refer to <https://unlicense.org>
@@ -0,0 +1,26 @@
1
+ Metadata-Version: 2.1
2
+ Name: sferriol-python
3
+ Version: 0.4.1
4
+ Summary: python utilities
5
+ Home-page: https://gitlab.in2p3.fr/sferriol-ip2i/sferriol-python
6
+ Author: Sylvain Ferriol
7
+ Author-email: s.ferriol@ipnl.in2p3.fr
8
+ Classifier: License :: OSI Approved :: The Unlicense (Unlicense)
9
+ Classifier: Operating System :: OS Independent
10
+ Classifier: Programming Language :: Python :: 3
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+
14
+ # sferriol-python
15
+
16
+ sferriol-python is a set of useful python libraries.
17
+
18
+ Clone the project
19
+
20
+ git clone git@gitlab.in2p3.fr:sferriol-ip2i/sferriol-python.git
21
+
22
+ Install it in your environment
23
+
24
+ python -m pip install .
25
+
26
+
@@ -0,0 +1,13 @@
1
+ # sferriol-python
2
+
3
+ sferriol-python is a set of useful python libraries.
4
+
5
+ Clone the project
6
+
7
+ git clone git@gitlab.in2p3.fr:sferriol-ip2i/sferriol-python.git
8
+
9
+ Install it in your environment
10
+
11
+ python -m pip install .
12
+
13
+
@@ -0,0 +1,10 @@
1
+ [build-system]
2
+ requires = [ "setuptools>=41", "wheel", "setuptools-git-versioning>=2.0,<3", ]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [tool.setuptools-git-versioning]
6
+ enabled = true
7
+ version_file = "VERSION"
8
+ count_commits_from_version_file = true
9
+ dev_template = "{tag}+{branch}{ccount}.git.{sha}"
10
+ dirty_template = "{tag}+{branch}{ccount}.git.{sha}.dirty"
@@ -0,0 +1,24 @@
1
+ [metadata]
2
+ author = Sylvain Ferriol
3
+ author_email = s.ferriol@ipnl.in2p3.fr
4
+ classifiers =
5
+ License :: OSI Approved :: The Unlicense (Unlicense)
6
+ Operating System :: OS Independent
7
+ Programming Language :: Python :: 3
8
+ description = python utilities
9
+ long_description = file: README.md
10
+ long_description_content_type = text/markdown
11
+ name = sferriol-python
12
+ url = https://gitlab.in2p3.fr/sferriol-ip2i/sferriol-python
13
+
14
+ [options]
15
+ packages = find_namespace:
16
+
17
+ [options.packages.find]
18
+ exclude = *.test
19
+ include = sferriol.*
20
+
21
+ [egg_info]
22
+ tag_build =
23
+ tag_date = 0
24
+
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ import importlib
4
+ import time
5
+ import warnings
6
+
7
+ from setuptools import setup
8
+
9
+ version = '0.1.0'
10
+
11
+ setup(
12
+ version_config=True,
13
+ )
@@ -0,0 +1,57 @@
1
+ import importlib.util
2
+ import pathlib
3
+ import time
4
+ import types
5
+ from typing import Any, Callable
6
+
7
+
8
+ def load_module_from_file(fpath):
9
+ """
10
+ Load a module from a python file.
11
+ The module name is the file name without file extension.
12
+ """
13
+ name = module_name_from_file(fpath)
14
+ spec = importlib.util.spec_from_file_location(name, fpath)
15
+ module = importlib.util.module_from_spec(spec)
16
+ spec.loader.exec_module(module)
17
+ return module
18
+
19
+
20
+ def loop_until(fct: Callable, ret: Any, every: float, timeout: float | int):
21
+ """Loops the execution of the function until it returns ret parameter
22
+
23
+ It raises TimeoutError if the expected value is not returned by the function
24
+
25
+ Args:
26
+ fct: Function to be called
27
+ ret: The expected return value
28
+ every: Number of seconds to wait at the end of each loop
29
+ timeout: Timeout duration
30
+ """
31
+ start_time = time.perf_counter()
32
+ while True:
33
+ if fct() == ret:
34
+ return
35
+ time.sleep(every)
36
+ if time.perf_counter() - start_time >= timeout:
37
+ raise TimeoutError()
38
+
39
+
40
+ def method(obj):
41
+ """
42
+ Decorator used to define a function as a new method of the object obj.
43
+ The method name is the function name.
44
+ """
45
+ def _(func):
46
+ name = func.__name__
47
+ setattr(obj, name, types.MethodType(func, obj))
48
+ return getattr(obj, name)
49
+
50
+ return _
51
+
52
+
53
+ def module_name_from_file(fpath):
54
+ """
55
+ Return The module name of the associated python file.
56
+ """
57
+ return pathlib.Path(fpath).stem
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ #
4
+ # Copyright 2020 sferriol <sferriol@ipnl.in2p3.fr>
5
+
6
+
7
+ class adict(dict):
8
+ """Attribute dictionary
9
+ """
10
+ def __delattr__(self, name):
11
+ self.__delitem__(name)
12
+
13
+ def __getattr__(self, name):
14
+ try:
15
+ ret = getattr(adict, name)
16
+ except AttributeError as e:
17
+ try:
18
+ ret = self.__getitem__(name)
19
+ except KeyError:
20
+ # if nothing is found, raise AttributeError instead of KeyError
21
+ raise e
22
+ return ret
23
+
24
+ def __setattr__(self, name, value):
25
+ self.__setitem__(name, value)
26
+
27
+
28
+ def as_adict(elt):
29
+ return dict_to_adict(elt)
30
+
31
+
32
+ class cdict(adict):
33
+ """Config dictionary.
34
+ c = cdict()
35
+ c['a.b'] = 2 # is equivalent to c['a'] = {'b':2}
36
+ assert c['a.b'] == c['a']['b']
37
+ assert c['a.b'] == c.a.b
38
+ """
39
+ def __getitem__(self, key):
40
+ di = self
41
+ l = key.split('.')
42
+ for k in l[:-1]:
43
+ di = di[k]
44
+ return adict.__getitem__(di, l[-1])
45
+
46
+ def __setitem__(self, key, value):
47
+ di = self
48
+ l = key.split('.')
49
+ for k in l[:-1]:
50
+ di.setdefault(k, adict())
51
+ di = di[k]
52
+ adict.__setitem__(di, l[-1], value)
53
+
54
+
55
+ def dict_merge(di_1, di_2):
56
+ def _dict(di_1, di_2):
57
+ for key, value in di_2.items():
58
+ if isinstance(value, dict):
59
+ if key not in di_1:
60
+ di_1[key] = {}
61
+ _dict(di_1[key], di_2[key])
62
+ else:
63
+ di_1[key] = value
64
+
65
+ _dict(di_1, di_2)
66
+ return di_1
67
+
68
+
69
+ def dict_to_adict(di):
70
+ # build an adict from a dictionary
71
+ # and all sub dictionary will be trannform in Attribute_Dict too
72
+ def _di2adi(elt):
73
+ if isinstance(elt, list):
74
+ return [_di2adi(e) for e in elt]
75
+ if isinstance(elt, dict):
76
+ adi = adict()
77
+ for k, v in elt.items():
78
+ adi[k] = _di2adi(v)
79
+ return adi
80
+ return elt
81
+
82
+ return _di2adi(di)
@@ -0,0 +1,16 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright 2023 sferriol <s.ferriol@ip2i.in2p3.fr>
4
+
5
+ import json
6
+ import tempfile
7
+
8
+
9
+ def dump_temporary(obj, prefix=None, dir=None):
10
+ """
11
+ Serialize obj as a JSON formatted stream to a temporary file and returns its file path. The file is created securely, using the same rules as mkstemp(). The user is responsible for deleting the temporary file when done with it.
12
+ """
13
+ _, fpath = tempfile.mkstemp(prefix=prefix, suffix='.json', dir=dir)
14
+ with open(fpath, 'w') as f:
15
+ json.dump(obj, f)
16
+ return fpath
@@ -0,0 +1,24 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright 2023 sferriol <s.ferriol@ip2i.in2p3.fr>
4
+ """Network utilities"""
5
+ import socket
6
+
7
+
8
+ def is_port_in_use(port: int) -> bool:
9
+ """Test if the port is already used"""
10
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
11
+ return s.connect_ex(('localhost', port)) == 0
12
+
13
+
14
+ def unused_port() -> int:
15
+ """Return an unsued port
16
+
17
+ Returns:
18
+ Port value
19
+ """
20
+ sock = socket.socket()
21
+ sock.bind(('127.0.0.1', 0))
22
+ _, port = sock.getsockname()
23
+ sock.close()
24
+ return port
@@ -0,0 +1,55 @@
1
+ # -*- coding: utf-8 -*-
2
+ import types
3
+
4
+
5
+ class Attribute:
6
+ def __init__(self, ns):
7
+ self.__sf__ns__ = ns
8
+
9
+ def __call__(self, fct):
10
+ setattr(self, fct.__name__, fct)
11
+
12
+ def __setattr__(self, name, value):
13
+ if hasattr(self, '__sf__ns__'):
14
+ ns = self.__sf__ns__
15
+ ns.__sf__obj_attributes__[name] = value
16
+ setattr(ns, name, value)
17
+ else:
18
+ object.__setattr__(self, name, value)
19
+
20
+
21
+ def attribute(ns):
22
+ return Attribute(ns)
23
+
24
+
25
+ class Object:
26
+ def __init__(self):
27
+ self.__sf__namespaces = dict()
28
+
29
+ def __set_ns__(self, ns):
30
+ for name, value in ns.__sf__obj_attributes__.items():
31
+ if callable(value):
32
+ value = types.MethodType(value, self)
33
+ setattr(self, name, value)
34
+ self.__sf__namespaces[ns.__sf__name__] = ns
35
+
36
+
37
+ class Namespace:
38
+ def __init__(self, name):
39
+ self.__sf__name__ = name
40
+ self.__sf__obj_attributes__ = dict()
41
+
42
+ def __call__(self, obj=None):
43
+ if obj is None:
44
+ obj = Object()
45
+ obj.__set_ns__(self)
46
+ return obj
47
+
48
+
49
+ def namespace():
50
+ def wrapper(fct):
51
+ ns = Namespace(fct.__name__)
52
+ fct(ns)
53
+ return ns
54
+
55
+ return wrapper
@@ -0,0 +1,11 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright 2023 sferriol <s.ferriol@ip2i.in2p3.fr>
4
+
5
+ import contextlib
6
+ import os
7
+
8
+
9
+ def remove_if_exists(fpath):
10
+ with contextlib.suppress(FileNotFoundError):
11
+ os.remove(fpath)
@@ -0,0 +1,26 @@
1
+ Metadata-Version: 2.1
2
+ Name: sferriol-python
3
+ Version: 0.4.1
4
+ Summary: python utilities
5
+ Home-page: https://gitlab.in2p3.fr/sferriol-ip2i/sferriol-python
6
+ Author: Sylvain Ferriol
7
+ Author-email: s.ferriol@ipnl.in2p3.fr
8
+ Classifier: License :: OSI Approved :: The Unlicense (Unlicense)
9
+ Classifier: Operating System :: OS Independent
10
+ Classifier: Programming Language :: Python :: 3
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+
14
+ # sferriol-python
15
+
16
+ sferriol-python is a set of useful python libraries.
17
+
18
+ Clone the project
19
+
20
+ git clone git@gitlab.in2p3.fr:sferriol-ip2i/sferriol-python.git
21
+
22
+ Install it in your environment
23
+
24
+ python -m pip install .
25
+
26
+
@@ -0,0 +1,15 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ setup.cfg
5
+ setup.py
6
+ sferriol/python/__init__.py
7
+ sferriol/python/json.py
8
+ sferriol/python/net.py
9
+ sferriol/python/object.py
10
+ sferriol/python/os.py
11
+ sferriol/python/dictionary/__init__.py
12
+ sferriol_python.egg-info/PKG-INFO
13
+ sferriol_python.egg-info/SOURCES.txt
14
+ sferriol_python.egg-info/dependency_links.txt
15
+ sferriol_python.egg-info/top_level.txt