Skip to content

Commit

Permalink
Merge pull request #45 from HansBug/dev/system
Browse files Browse the repository at this point in the history
dev(hansbug): add python and package version support
  • Loading branch information
HansBug authored May 20, 2022
2 parents ceb6aa9 + 037cfb4 commit f09654c
Show file tree
Hide file tree
Showing 15 changed files with 257 additions and 5 deletions.
10 changes: 10 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@ jobs:
echo "OS_NAME=MacOS" >> $GITHUB_ENV
echo "IS_WIN=" >> $GITHUB_ENV
echo "IS_MAC=1" >> $GITHUB_ENV
- name: Set environment for Cpython
if: ${{ !contains(matrix.python-version, 'pypy') }}
shell: bash
run: |
echo "IS_PYPY=" >> $GITHUB_ENV
- name: Set environment for PyPy
if: ${{ contains(matrix.python-version, 'pypy') }}
shell: bash
run: |
echo "IS_PYPY=1" >> $GITHUB_ENV
- name: Checkout code
uses: actions/checkout@v2
with:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Some useful functions and classes in Python infrastructure development.
You can simply install it with `pip` command line from the official PyPI site.

```shell
pip install hbutils
package install hbutils
```

For more information about installation, you can refer
Expand Down
1 change: 1 addition & 0 deletions docs/source/api_doc/system/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ hbutils.system

filesystem
os
python

50 changes: 50 additions & 0 deletions docs/source/api_doc/system/python.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
hbutils.system.python
========================================

.. currentmodule:: hbutils.system.python

.. automodule:: hbutils.system.python


python_version
-----------------------------------

.. autofunction:: python_version



is_cpython
-----------------------------------

.. autofunction:: is_cpython



is_ironpython
-----------------------------------

.. autofunction:: is_ironpython



is_jython
-----------------------------------

.. autofunction:: is_jython



is_pypy
-----------------------------------

.. autofunction:: is_pypy



package_version
-----------------------------------

.. autofunction:: package_version



1 change: 1 addition & 0 deletions hbutils/system/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
from .filesystem import *
from .os import *
from .python import *
3 changes: 3 additions & 0 deletions hbutils/system/python/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .implementation import *
from .package import *
from .version import *
66 changes: 66 additions & 0 deletions hbutils/system/python/implementation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import platform
from enum import IntEnum, unique
from functools import lru_cache

from ...model import int_enum_loads

__all__ = [
'is_cpython',
'is_ironpython',
'is_jython',
'is_pypy',
]


@int_enum_loads(name_preprocess=str.upper)
@unique
class PythonImplementation(IntEnum):
CPYTHON = 1
IRONPYTHON = 2
JYTHON = 3
PYPY = 4


@lru_cache()
def _get_python_implementation() -> PythonImplementation:
return PythonImplementation.loads(platform.python_implementation())


def is_cpython() -> bool:
"""
Overview:
Return ``True`` is current python is CPython, otherwise return ``False``.
:return: Current python is CPython or not.
"""
return _get_python_implementation() == PythonImplementation.CPYTHON


def is_ironpython() -> bool:
"""
Overview:
Return ``True`` is current python is IronPython, otherwise return ``False``.
:return: Current python is IronPython or not.
"""
return _get_python_implementation() == PythonImplementation.IRONPYTHON


def is_jython() -> bool:
"""
Overview:
Return ``True`` is current python is Jython, otherwise return ``False``.
:return: Current python is Jython or not.
"""
return _get_python_implementation() == PythonImplementation.JYTHON


def is_pypy() -> bool:
"""
Overview:
Return ``True`` is current python is PyPy, otherwise return ``False``.
:return: Current python is PyPy or not.
"""
return _get_python_implementation() == PythonImplementation.PYPY
41 changes: 41 additions & 0 deletions hbutils/system/python/package.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from typing import Dict, Optional

from packaging.version import Version
from pkg_resources import working_set, parse_version

__all__ = [
'package_version',
]


def _get_packages() -> Dict[str, Version]:
return {
i.key.lower(): i.version
for i in working_set
}


def package_version(name: str) -> Optional[Version]:
"""
Overview:
Get version of package with given ``name``.
:param name: Name of the package, case is not sensitive.
:return: A :class:`packing.version.Version` object. If the package is not installed, return ``None``.
Examples::
>>> from hbutils.system import package_version
>>>
>>> package_version('pip')
<Version('21.3.1')>
>>> package_version('setuptools')
<Version('59.6.0')>
>>> package_version('not_a_package')
None
"""
_packages = _get_packages()
_name = name.lower()
if _name in _packages:
return parse_version(_packages[name])
else:
return None
24 changes: 24 additions & 0 deletions hbutils/system/python/version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import platform

from packaging.version import Version
from pkg_resources import parse_version

__all__ = [
'python_version',
]


def python_version() -> Version:
"""
Overview:
Get version of python.
:return: Version of python.
Examples::
>>> from hbutils.system import python_version
>>>
>>> python_version()
Version('3.8.1') # for example
"""
return parse_version(platform.python_version())
Empty file added test/system/python/__init__.py
Empty file.
18 changes: 18 additions & 0 deletions test/system/python/test_implementation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from hbutils.system import is_cpython, is_pypy, is_jython, is_ironpython
from ...testings import cpython_mark, pypy_mark


class TestSystemPythonImplementation:
@cpython_mark
def test_is_cpython(self):
assert is_cpython()
assert not is_pypy()
assert not is_jython()
assert not is_ironpython()

@pypy_mark
def test_is_pypy(self):
assert not is_cpython()
assert is_pypy()
assert not is_jython()
assert not is_ironpython()
15 changes: 15 additions & 0 deletions test/system/python/test_package.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import pytest
from pkg_resources import parse_version

from hbutils.system import package_version
from .test_version import _Version


@pytest.mark.unittest
class TestSystemPythonPackage:
def test_package_version(self):
assert package_version("pip") >= parse_version("19")
assert isinstance(package_version("chardet"), _Version)
assert package_version("chardet") >= parse_version("3.0.4")
assert package_version("chardet") < parse_version("5")
assert package_version("This_is_an_fxxking_name") is None
19 changes: 19 additions & 0 deletions test/system/python/test_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import sys

import pytest
from pkg_resources import parse_version

from hbutils.system import python_version

_Version = type(parse_version("0.0.1"))


@pytest.mark.unittest
class TestSystemPythonVersion:
def test_python_version(self):
_actual_version = sys.version_info
_get_version = python_version()
assert isinstance(_get_version, _Version)
assert _get_version.major == _actual_version.major
assert _get_version.minor == _actual_version.minor
assert _get_version.micro == _actual_version.micro
2 changes: 1 addition & 1 deletion test/testings/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from .platform import linux_mark, macos_mark, windows_mark
from .platform import linux_mark, macos_mark, windows_mark, pypy_mark, cpython_mark
10 changes: 7 additions & 3 deletions test/testings/platform.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import os
import platform
import pytest

platform.system()
import pytest

_is_win = bool(os.environ.get('IS_WIN', None))
_is_macos = bool(os.environ.get('IS_MAC', None))
Expand All @@ -11,3 +9,9 @@
windows_mark = pytest.mark.unittest if _is_win else pytest.mark.ignore
macos_mark = pytest.mark.unittest if _is_macos else pytest.mark.ignore
linux_mark = pytest.mark.unittest if _is_linux else pytest.mark.ignore

_is_pypy = bool(os.environ.get('IS_PYPY', None))
_is_cpython = not _is_pypy

pypy_mark = pytest.mark.unittest if _is_pypy else pytest.mark.ignore
cpython_mark = pytest.mark.unittest if _is_cpython else pytest.mark.ignore

0 comments on commit f09654c

Please sign in to comment.