diff options
Diffstat (limited to 'python-pytong.spec')
-rw-r--r-- | python-pytong.spec | 378 |
1 files changed, 378 insertions, 0 deletions
diff --git a/python-pytong.spec b/python-pytong.spec new file mode 100644 index 0000000..84ca1f4 --- /dev/null +++ b/python-pytong.spec @@ -0,0 +1,378 @@ +%global _empty_manifest_terminate_build 0 +Name: python-pytong +Version: 0.2.2 +Release: 1 +Summary: Rich Tong's Fine Utilities +License: MIT License +URL: https://github.com/richtong/pytong +Source0: https://mirrors.aliyun.com/pypi/web/packages/e0/20/37cde265ca82cf27c9192dd991e6a49876b5eb406b9b023a178f20badf33/pytong-0.2.2.tar.gz +BuildArch: noarch + + +%description +%{asctime}s | LogRecord creation time +%{filename}s | Current file +%{funcName}s | Current function +%{levelname}s | Logging level (eg DEBUG, INFO) +%{levelno}s | Logging number {eg 1-100} +%{lineno}d | Current line number +%{message}s | Message of log +%{module}s | File without the .py +%{name}s | Name of the logger +%{pathname}s | Full path of file +%{process}d | Process id +%{processName}s | Name of process +%{thread}d | Thread id +%{threadName}s | Thread name +So most of the time you will be fine with this level of detail, the main thing +missing is that for class objects, you are missing some detail, but you know +the file location and the line number. +The second trick is that if you want more logging detail then in a function you +can create a logger by create more dotted names, : +```python +import logging +# this logger will be used for all functions in this module +log = logging.getLogger(__name__) +class new_class(): + def __init__(self): + # use the class logger for all methods that appends the class type to the + # current file/module + self.log = logging.getLogger(__name__ + '.' + type(self).__name__) + def add(): + # log with the instance name and class type + self.log("Entering a new method to add to the database") +``` +### Version 2 Logging helper function +This is much simpler than version 1 and the only helper needed is to load the +YAML file with the configuration: +```python +import logging +from pytong import config_log +# this is the module wide logging by setting a global variable +log = logging.getLogger(__name__) +# setLog creates a logger named <module path>/<class name> +@setLog +class test: + def __init__(self): + # the logger name is '__main__.test' + self.log(f"In {self=}") +def main(): + config_log() + # the logger name is '__main__' and funcname will be printed + log.debug(f"{log=} created") +``` +## Version 1 Logging (deprecated) +Usage is pretty simple, we use inheritance to have the right logging compared +with v2 which uses a class decorator. +```python +from pytong import Log, BaseLog #type: ignore +# then for each class you create have a log member to remember it +# set a log_root which is the top and then on each Class initiation +# instantiate a new class +# if you set this base class you get logging +class <Your Class>(BaseLog) + # Use the decorator pattern that Keras and other use with chaining + # so every class has a set_logger method that returns the class + # this allows constructs like foo.set_logger.next_method... + # note that we pass the name which is by default __name__ + # which for classes is the class name + def set_logger(self, name: str = __name__) -> <Your Class>: + """Set Log. + Setup the root logger and log + """ + self.log_root = Log(name) + self.log = self.log_root.log + return self + def <some method>(self, <0ther functions>): + # a convenience as self.log is a lot of typing + log = self.log + log.debug(f'I am here with {log=}') +``` +## Log by call tree +The logging module automatically creates loggers and lists logs by the call +stack. It also sends different prefixes for class calls. +## Building +You can install the needed pieces with and then upload to test.pypi.org or +pypi.org +```sh +make pip-install +# edit .envrc with the your API Token for test do not include the pypi- that is +# added in the makefile +make test-pypi +# add the pypi api token without the pypi- +make pypi +``` +## Testing +The test scaffolding is not working yet. +## File Layout +We adopt the scheme that seems a little redundent where we have a strudture +that is ./pytong/src/pytong and the tests are in ./pytong/tests. +[Ionel](https://blog.ionelmc.ro/2014/05/25/python-packaging/#the-structure) +explains why this is important. And also +[HYnek](https://hynek.me/articles/testing-packaging/) explains why as well. +The biggest reason for this is that you are forced to install code and can +check for packaging breaks. And you don't want to include test modules with +your source code. + +%package -n python3-pytong +Summary: Rich Tong's Fine Utilities +Provides: python-pytong +BuildRequires: python3-devel +BuildRequires: python3-setuptools +BuildRequires: python3-pip +%description -n python3-pytong +%{asctime}s | LogRecord creation time +%{filename}s | Current file +%{funcName}s | Current function +%{levelname}s | Logging level (eg DEBUG, INFO) +%{levelno}s | Logging number {eg 1-100} +%{lineno}d | Current line number +%{message}s | Message of log +%{module}s | File without the .py +%{name}s | Name of the logger +%{pathname}s | Full path of file +%{process}d | Process id +%{processName}s | Name of process +%{thread}d | Thread id +%{threadName}s | Thread name +So most of the time you will be fine with this level of detail, the main thing +missing is that for class objects, you are missing some detail, but you know +the file location and the line number. +The second trick is that if you want more logging detail then in a function you +can create a logger by create more dotted names, : +```python +import logging +# this logger will be used for all functions in this module +log = logging.getLogger(__name__) +class new_class(): + def __init__(self): + # use the class logger for all methods that appends the class type to the + # current file/module + self.log = logging.getLogger(__name__ + '.' + type(self).__name__) + def add(): + # log with the instance name and class type + self.log("Entering a new method to add to the database") +``` +### Version 2 Logging helper function +This is much simpler than version 1 and the only helper needed is to load the +YAML file with the configuration: +```python +import logging +from pytong import config_log +# this is the module wide logging by setting a global variable +log = logging.getLogger(__name__) +# setLog creates a logger named <module path>/<class name> +@setLog +class test: + def __init__(self): + # the logger name is '__main__.test' + self.log(f"In {self=}") +def main(): + config_log() + # the logger name is '__main__' and funcname will be printed + log.debug(f"{log=} created") +``` +## Version 1 Logging (deprecated) +Usage is pretty simple, we use inheritance to have the right logging compared +with v2 which uses a class decorator. +```python +from pytong import Log, BaseLog #type: ignore +# then for each class you create have a log member to remember it +# set a log_root which is the top and then on each Class initiation +# instantiate a new class +# if you set this base class you get logging +class <Your Class>(BaseLog) + # Use the decorator pattern that Keras and other use with chaining + # so every class has a set_logger method that returns the class + # this allows constructs like foo.set_logger.next_method... + # note that we pass the name which is by default __name__ + # which for classes is the class name + def set_logger(self, name: str = __name__) -> <Your Class>: + """Set Log. + Setup the root logger and log + """ + self.log_root = Log(name) + self.log = self.log_root.log + return self + def <some method>(self, <0ther functions>): + # a convenience as self.log is a lot of typing + log = self.log + log.debug(f'I am here with {log=}') +``` +## Log by call tree +The logging module automatically creates loggers and lists logs by the call +stack. It also sends different prefixes for class calls. +## Building +You can install the needed pieces with and then upload to test.pypi.org or +pypi.org +```sh +make pip-install +# edit .envrc with the your API Token for test do not include the pypi- that is +# added in the makefile +make test-pypi +# add the pypi api token without the pypi- +make pypi +``` +## Testing +The test scaffolding is not working yet. +## File Layout +We adopt the scheme that seems a little redundent where we have a strudture +that is ./pytong/src/pytong and the tests are in ./pytong/tests. +[Ionel](https://blog.ionelmc.ro/2014/05/25/python-packaging/#the-structure) +explains why this is important. And also +[HYnek](https://hynek.me/articles/testing-packaging/) explains why as well. +The biggest reason for this is that you are forced to install code and can +check for packaging breaks. And you don't want to include test modules with +your source code. + +%package help +Summary: Development documents and examples for pytong +Provides: python3-pytong-doc +%description help +%{asctime}s | LogRecord creation time +%{filename}s | Current file +%{funcName}s | Current function +%{levelname}s | Logging level (eg DEBUG, INFO) +%{levelno}s | Logging number {eg 1-100} +%{lineno}d | Current line number +%{message}s | Message of log +%{module}s | File without the .py +%{name}s | Name of the logger +%{pathname}s | Full path of file +%{process}d | Process id +%{processName}s | Name of process +%{thread}d | Thread id +%{threadName}s | Thread name +So most of the time you will be fine with this level of detail, the main thing +missing is that for class objects, you are missing some detail, but you know +the file location and the line number. +The second trick is that if you want more logging detail then in a function you +can create a logger by create more dotted names, : +```python +import logging +# this logger will be used for all functions in this module +log = logging.getLogger(__name__) +class new_class(): + def __init__(self): + # use the class logger for all methods that appends the class type to the + # current file/module + self.log = logging.getLogger(__name__ + '.' + type(self).__name__) + def add(): + # log with the instance name and class type + self.log("Entering a new method to add to the database") +``` +### Version 2 Logging helper function +This is much simpler than version 1 and the only helper needed is to load the +YAML file with the configuration: +```python +import logging +from pytong import config_log +# this is the module wide logging by setting a global variable +log = logging.getLogger(__name__) +# setLog creates a logger named <module path>/<class name> +@setLog +class test: + def __init__(self): + # the logger name is '__main__.test' + self.log(f"In {self=}") +def main(): + config_log() + # the logger name is '__main__' and funcname will be printed + log.debug(f"{log=} created") +``` +## Version 1 Logging (deprecated) +Usage is pretty simple, we use inheritance to have the right logging compared +with v2 which uses a class decorator. +```python +from pytong import Log, BaseLog #type: ignore +# then for each class you create have a log member to remember it +# set a log_root which is the top and then on each Class initiation +# instantiate a new class +# if you set this base class you get logging +class <Your Class>(BaseLog) + # Use the decorator pattern that Keras and other use with chaining + # so every class has a set_logger method that returns the class + # this allows constructs like foo.set_logger.next_method... + # note that we pass the name which is by default __name__ + # which for classes is the class name + def set_logger(self, name: str = __name__) -> <Your Class>: + """Set Log. + Setup the root logger and log + """ + self.log_root = Log(name) + self.log = self.log_root.log + return self + def <some method>(self, <0ther functions>): + # a convenience as self.log is a lot of typing + log = self.log + log.debug(f'I am here with {log=}') +``` +## Log by call tree +The logging module automatically creates loggers and lists logs by the call +stack. It also sends different prefixes for class calls. +## Building +You can install the needed pieces with and then upload to test.pypi.org or +pypi.org +```sh +make pip-install +# edit .envrc with the your API Token for test do not include the pypi- that is +# added in the makefile +make test-pypi +# add the pypi api token without the pypi- +make pypi +``` +## Testing +The test scaffolding is not working yet. +## File Layout +We adopt the scheme that seems a little redundent where we have a strudture +that is ./pytong/src/pytong and the tests are in ./pytong/tests. +[Ionel](https://blog.ionelmc.ro/2014/05/25/python-packaging/#the-structure) +explains why this is important. And also +[HYnek](https://hynek.me/articles/testing-packaging/) explains why as well. +The biggest reason for this is that you are forced to install code and can +check for packaging breaks. And you don't want to include test modules with +your source code. + +%prep +%autosetup -n pytong-0.2.2 + +%build +%py3_build + +%install +%py3_install +install -d -m755 %{buildroot}/%{_pkgdocdir} +if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi +if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi +if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi +if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi +pushd %{buildroot} +if [ -d usr/lib ]; then + find usr/lib -type f -printf "\"/%h/%f\"\n" >> filelist.lst +fi +if [ -d usr/lib64 ]; then + find usr/lib64 -type f -printf "\"/%h/%f\"\n" >> filelist.lst +fi +if [ -d usr/bin ]; then + find usr/bin -type f -printf "\"/%h/%f\"\n" >> filelist.lst +fi +if [ -d usr/sbin ]; then + find usr/sbin -type f -printf "\"/%h/%f\"\n" >> filelist.lst +fi +touch doclist.lst +if [ -d usr/share/man ]; then + find usr/share/man -type f -printf "\"/%h/%f.gz\"\n" >> doclist.lst +fi +popd +mv %{buildroot}/filelist.lst . +mv %{buildroot}/doclist.lst . + +%files -n python3-pytong -f filelist.lst +%dir %{python3_sitelib}/* + +%files help -f doclist.lst +%{_docdir}/* + +%changelog +* Tue Jun 20 2023 Python_Bot <Python_Bot@openeuler.org> - 0.2.2-1 +- Package Spec generated |