init
This commit is contained in:
@@ -0,0 +1,227 @@
|
||||
"""The knowledge base.
|
||||
|
||||
Knowledge
|
||||
=========
|
||||
|
||||
It contains, for instance, known odd locations of version information for
|
||||
particular modules (``VERSION_ATTRIBUTES``, ``VERSION_METHODS``)
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import sysconfig
|
||||
from typing import TYPE_CHECKING, Literal
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Callable
|
||||
|
||||
PACKAGE_ALIASES = {
|
||||
'vtkmodules': 'vtk',
|
||||
'vtkmodules.all': 'vtk',
|
||||
}
|
||||
|
||||
# Define unusual version locations
|
||||
VERSION_ATTRIBUTES = {
|
||||
'PyQt5': 'Qt.PYQT_VERSION_STR',
|
||||
'sip': 'SIP_VERSION_STR',
|
||||
}
|
||||
|
||||
|
||||
def get_pyqt5_version() -> str:
|
||||
"""Return the PyQt5 version."""
|
||||
try:
|
||||
from PyQt5.Qt import PYQT_VERSION_STR
|
||||
except ImportError:
|
||||
return 'Version unknown'
|
||||
|
||||
return PYQT_VERSION_STR
|
||||
|
||||
|
||||
VERSION_METHODS: dict[str, Callable[[], str]] = {
|
||||
'PyQt5': get_pyqt5_version,
|
||||
}
|
||||
|
||||
|
||||
# Check the environments
|
||||
def in_ipython() -> bool:
|
||||
"""Check if we are in a IPython environment.
|
||||
|
||||
Returns
|
||||
-------
|
||||
bool : True
|
||||
``True`` when in an IPython environment.
|
||||
|
||||
"""
|
||||
try:
|
||||
__IPYTHON__ # noqa: B018
|
||||
except NameError:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def in_ipykernel() -> bool:
|
||||
"""Check if in a ipykernel (most likely Jupyter) environment.
|
||||
|
||||
Warning:
|
||||
-------
|
||||
There is no way to tell if the code is being executed in a notebook
|
||||
(Jupyter Notebook or Jupyter Lab) or a kernel is used but executed in a
|
||||
QtConsole, or in an IPython console, or any other frontend GUI. However, if
|
||||
`in_ipykernel` returns True, you are most likely in a Jupyter Notebook/Lab,
|
||||
just keep it in mind that there are other possibilities.
|
||||
|
||||
Returns:
|
||||
-------
|
||||
bool : True if using an ipykernel
|
||||
|
||||
"""
|
||||
ipykernel = False
|
||||
if in_ipython():
|
||||
try:
|
||||
ipykernel: bool = type(get_ipython()).__module__.startswith('ipykernel.')
|
||||
except NameError:
|
||||
pass
|
||||
return ipykernel
|
||||
|
||||
|
||||
def get_standard_lib_modules() -> set[str]:
|
||||
"""Return a set of the names of all modules in the standard library."""
|
||||
site_path = Path(sysconfig.get_path('stdlib'))
|
||||
if getattr(sys, 'frozen', False): # within pyinstaller
|
||||
lib_path = site_path / '..'
|
||||
if lib_path.is_dir():
|
||||
names = lib_path.iterdir()
|
||||
stdlib_pkgs = {p.stem for p in names if p.suffix == '.py'}
|
||||
else:
|
||||
stdlib_pkgs = {}
|
||||
|
||||
else:
|
||||
names = site_path.iterdir()
|
||||
stdlib_pkgs = {p.stem if p.suffix == '.py' else p.name for p in names}
|
||||
|
||||
return {
|
||||
'python',
|
||||
'sys',
|
||||
'__builtin__',
|
||||
'__builtins__',
|
||||
'builtins',
|
||||
'session',
|
||||
'math',
|
||||
'itertools',
|
||||
'binascii',
|
||||
'array',
|
||||
'atexit',
|
||||
'fcntl',
|
||||
'errno',
|
||||
'gc',
|
||||
'time',
|
||||
'unicodedata',
|
||||
'mmap',
|
||||
}.union(stdlib_pkgs)
|
||||
|
||||
|
||||
def version_tuple(v: str) -> tuple[int, ...]:
|
||||
"""Convert a version string to a tuple containing ints.
|
||||
|
||||
Non-numeric version strings will be converted to 0. For example:
|
||||
``'0.28.0dev0'`` will be converted to ``'0.28.0'``
|
||||
|
||||
Returns
|
||||
-------
|
||||
ver_tuple : tuple
|
||||
Length 3 tuple representing the major, minor, and patch
|
||||
version.
|
||||
|
||||
"""
|
||||
split_v = v.split('.')
|
||||
while len(split_v) < 3:
|
||||
split_v.append('0')
|
||||
|
||||
if len(split_v) > 3:
|
||||
msg = 'Version strings containing more than three parts cannot be parsed'
|
||||
raise ValueError(msg)
|
||||
|
||||
vals: list[int] = []
|
||||
for item in split_v:
|
||||
if item.isnumeric():
|
||||
vals.append(int(item))
|
||||
else:
|
||||
vals.append(0)
|
||||
|
||||
return tuple(vals)
|
||||
|
||||
|
||||
def meets_version(version: str, meets: str) -> bool:
|
||||
"""Check if a version string meets a minimum version.
|
||||
|
||||
This is a simplified way to compare version strings. For a more robust
|
||||
tool, please check out the ``packaging`` library:
|
||||
|
||||
https://github.com/pypa/packaging
|
||||
|
||||
Parameters
|
||||
----------
|
||||
version : str
|
||||
Version string. For example ``'0.25.1'``.
|
||||
|
||||
meets : str
|
||||
Version string. For example ``'0.25.2'``.
|
||||
|
||||
Returns
|
||||
-------
|
||||
newer : bool
|
||||
True if version ``version`` is greater or equal to version ``meets``.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> meets_version('0.25.1', '0.25.2')
|
||||
False
|
||||
|
||||
>>> meets_version('0.26.0', '0.25.2')
|
||||
True
|
||||
|
||||
"""
|
||||
va = version_tuple(version)
|
||||
vb = version_tuple(meets)
|
||||
|
||||
if len(va) != len(vb):
|
||||
msg = 'Versions are not comparable.'
|
||||
raise AssertionError(msg)
|
||||
|
||||
for i in range(len(va)):
|
||||
if va[i] > vb[i]:
|
||||
return True
|
||||
if va[i] < vb[i]:
|
||||
return False
|
||||
|
||||
# Arrived here if same version
|
||||
return True
|
||||
|
||||
|
||||
def get_filesystem_type() -> str | Literal[False]:
|
||||
"""Get the type of the file system at the path of the scooby package."""
|
||||
try:
|
||||
import psutil # lazy-load see PR#85
|
||||
except ImportError:
|
||||
psutil = False
|
||||
from pathlib import Path # lazy-load see PR#85
|
||||
import platform # lazy-load see PR#85
|
||||
|
||||
# Skip Windows due to https://github.com/banesullivan/scooby/issues/75
|
||||
fs_type: str | Literal[False]
|
||||
if psutil and platform.system() != 'Windows':
|
||||
# Code by https://stackoverflow.com/a/35291824/10504481
|
||||
my_path = str(Path(__file__).resolve())
|
||||
best_match = ''
|
||||
fs_type = ''
|
||||
for part in psutil.disk_partitions():
|
||||
if my_path.startswith(part.mountpoint) and len(best_match) < len(part.mountpoint):
|
||||
fs_type = part.fstype
|
||||
best_match = part.mountpoint
|
||||
else:
|
||||
fs_type = False
|
||||
return fs_type
|
||||
Reference in New Issue
Block a user