diff --git a/cardinal_pythonlib/datetimefunc.py b/cardinal_pythonlib/datetimefunc.py index 2e5db36..0254ed3 100644 --- a/cardinal_pythonlib/datetimefunc.py +++ b/cardinal_pythonlib/datetimefunc.py @@ -46,35 +46,19 @@ from string import Formatter from typing import Any, Optional, Union -try: - # noinspection PyPackageRequirements - from arrow import Arrow -except ImportError: - Arrow = None - -try: - import dateutil.parser -except ImportError: - dateutil = None - +from arrow import Arrow +import dateutil.parser from isodate.isoduration import parse_duration, Duration as IsodateDuration import pendulum from pendulum import Date, DateTime, Duration, Time from pendulum.tz import local_timezone from pendulum.tz.timezone import Timezone -if Arrow is not None: - PotentialDatetimeType = Union[ - None, datetime.datetime, datetime.date, DateTime, str, Arrow - ] - DateTimeLikeType = Union[datetime.datetime, DateTime, Arrow] - DateLikeType = Union[datetime.date, DateTime, Arrow] -else: - PotentialDatetimeType = Union[ - None, datetime.datetime, datetime.date, DateTime, str - ] - DateTimeLikeType = Union[datetime.datetime, DateTime] - DateLikeType = Union[datetime.date, DateTime] +PotentialDatetimeType = Union[ + None, datetime.datetime, datetime.date, DateTime, str, Arrow +] +DateTimeLikeType = Union[datetime.datetime, DateTime, Arrow] +DateLikeType = Union[datetime.date, DateTime, Arrow] log = logging.getLogger(__name__) diff --git a/cardinal_pythonlib/extract_text.py b/cardinal_pythonlib/extract_text.py index e4cdb94..41dbd52 100755 --- a/cardinal_pythonlib/extract_text.py +++ b/cardinal_pythonlib/extract_text.py @@ -96,46 +96,21 @@ Optional, ) from xml.etree import ElementTree as ElementTree - -# ... cElementTree used to be the fast implementation; now ElementTree is fast -# and cElementTree is deprecated; see -# https://docs.python.org/3.4/library/xml.etree.elementtree.html import zipfile import bs4 +import chardet +from chardet.universaldetector import UniversalDetector +import pdfminer # pip install pdfminer.six +import pdfminer.pdfinterp +import pdfminer.converter +import pdfminer.layout +import pdfminer.pdfpage import prettytable from semantic_version import Version from cardinal_pythonlib.logs import get_brace_style_log_with_null_handler -try: - import chardet - from chardet.universaldetector import UniversalDetector -except ImportError: - chardet = None - UniversalDetector = None - -try: - # noinspection PyPackageRequirements - import pdfminer # pip install pdfminer - - assert ( - int(pdfminer.__version__) > 20191010 - ), "pdfminer installed but too old" # version string is e.g. '20191125' - - # noinspection PyPackageRequirements - import pdfminer.pdfinterp - - # noinspection PyPackageRequirements - import pdfminer.converter - - # noinspection PyPackageRequirements - import pdfminer.layout - - # noinspection PyPackageRequirements - import pdfminer.pdfpage -except ImportError: - pdfminer = None log = get_brace_style_log_with_null_handler(__name__) diff --git a/cardinal_pythonlib/getch.py b/cardinal_pythonlib/getch.py index c59eead..b0cf60f 100644 --- a/cardinal_pythonlib/getch.py +++ b/cardinal_pythonlib/getch.py @@ -34,13 +34,13 @@ import sys try: - import msvcrt # Windows only + import msvcrt # Windows only, but part of core Python under Windows termios = None tty = None except ImportError: msvcrt = None - import termios # Unix only + import termios # Unix only; tty/termios are part of core Python under Unix import tty # requires termios, so Unix only # noqa: F401 diff --git a/cardinal_pythonlib/hash.py b/cardinal_pythonlib/hash.py index 49e373b..71906e4 100644 --- a/cardinal_pythonlib/hash.py +++ b/cardinal_pythonlib/hash.py @@ -64,14 +64,6 @@ except ImportError: mmh3 = None -# try: -# import xxhash -# pyhashxx = None -# except ImportError: -# xxhash = None -# import pyhashxx - - # https://docs.python.org/3/library/platform.html#platform.architecture IS_64_BIT = sys.maxsize > 2**32 TIMING_HASH = "hash" diff --git a/cardinal_pythonlib/module_version.py b/cardinal_pythonlib/module_version.py index 48475a7..f18f9a0 100644 --- a/cardinal_pythonlib/module_version.py +++ b/cardinal_pythonlib/module_version.py @@ -35,23 +35,13 @@ # Imports # ============================================================================= -import sys +from importlib.metadata import version # structure for Python 3.8 or higher from semantic_version import Version # noinspection PyUnresolvedReferences import cardinal_pythonlib.ensure_test_executed_correctly # noqa: F401 -if sys.version_info > (3, 8): - # Python 3.8 or higher - # noinspection PyCompatibility - from importlib.metadata import version -else: - try: - from importlib_metadata import version - except ImportError: - raise - # ============================================================================= # Report Python module versions diff --git a/cardinal_pythonlib/spreadsheets.py b/cardinal_pythonlib/spreadsheets.py index 1b089c2..d5e5d4e 100644 --- a/cardinal_pythonlib/spreadsheets.py +++ b/cardinal_pythonlib/spreadsheets.py @@ -38,6 +38,10 @@ import logging from typing import Any, Dict, Iterable, List, Optional, Sequence, Tuple, Union +import xlrd +from xlrd import Book +from xlrd.sheet import Cell, Sheet + from cardinal_pythonlib.datetimefunc import ( coerce_to_pendulum, pendulum_to_datetime_stripping_tz, @@ -45,18 +49,6 @@ from cardinal_pythonlib.progress import ActivityCounter from cardinal_pythonlib.reprfunc import simple_repr -try: - # noinspection PyPackageRequirements - import xlrd - - # noinspection PyPackageRequirements - from xlrd import Book - - # noinspection PyPackageRequirements - from xlrd.sheet import Cell, Sheet -except ImportError: - raise ImportError("You must install the 'xlrd' package.") - log = logging.getLogger(__name__) diff --git a/cardinal_pythonlib/sqlalchemy/arrow_types.py b/cardinal_pythonlib/sqlalchemy/arrow_types.py index 1bd4886..55c8761 100644 --- a/cardinal_pythonlib/sqlalchemy/arrow_types.py +++ b/cardinal_pythonlib/sqlalchemy/arrow_types.py @@ -30,7 +30,6 @@ import datetime from typing import Any, Iterable, Optional -# noinspection PyUnresolvedReferences import arrow import sqlalchemy.dialects.mssql import sqlalchemy.dialects.mysql diff --git a/docs/source/external_dependencies.rst b/docs/source/external_dependencies.rst index a43814c..04baaf5 100644 --- a/docs/source/external_dependencies.rst +++ b/docs/source/external_dependencies.rst @@ -18,17 +18,21 @@ External libraries ------------------ - -This package also installs (and uses or extends): +This package also installs (and uses or extends) the following packages, which +are generally "pure Python", meaning that they can easily be installed e.g. on +a Windows computer with no C compiler system installed. - ``alembic``: http://alembic.zzzcomputing.com/ - ``appdirs``: https://pypi.org/project/appdirs/ +- ``arrow``: https://arrow.readthedocs.io/ - ``beautifulsoup4``: https://www.crummy.com/software/BeautifulSoup/bs4/doc/ +- ``chardet``: https://chardet.readthedocs.io/en/latest/ - ``colorlog``: https://pypi.org/project/colorlog/ - ``isodate``: https://pypi.org/project/isodate/ - ``numpy``: http://www.numpy.org/ - ``openpyxl``: https://openpyxl.readthedocs.io/ - ``pandas``: https://pandas.pydata.org/ +- ``pdfminer.six``: https://pdfminersix.readthedocs.io/en/latest/ - ``pendulum``: https://pendulum.eustace.io/ - ``prettytable``: https://pypi.org/project/PrettyTable/ - ``psutil``: https://pypi.org/project/psutil/ @@ -40,26 +44,40 @@ This package also installs (and uses or extends): - ``semantic_version``: https://pypi.org/project/semantic_version/ - ``SQLAlchemy``: https://www.sqlalchemy.org/ - ``sqlparse``: https://sqlparse.readthedocs.io/ +- ``xlrd``: https://pypi.org/project/xlrd/ -The following will be used, if present (and an exception raised if you use -library code that requires one of these packages without it being installed): +The following packages will be used, if present, and an exception raised if you +use library code that requires one of these packages without it being +installed. They include large packages (e.g. Django), some other "less core" +aspects, and packages that require a C compiler and so may be harder to install +in some contexts. -- ``arrow``: https://arrow.readthedocs.io/ -- ``bcrypt``: https://pypi.org/project/bcrypt/ +- ``bcrypt``: https://pypi.org/project/bcrypt/ (C-based) - ``colander``: https://docs.pylonsproject.org/projects/colander/ +- ``cryptography``: https://cryptography.io/ - ``deform``: https://docs.pylonsproject.org/projects/deform/ -- ``Django``: https://www.djangoproject.com/ +- ``Django`` >= 4.2: https://www.djangoproject.com/ - ``dogpile.cache``: https://dogpilecache.readthedocs.io/ +- ``libChEBIpy``: https://pypi.org/project/libChEBIpy/ (Python 2 only?) - ``pyramid``: https://trypyramid.com/ -- ``webob``: https://webob.org/ (used by Pyramid) +- ``webob``: https://webob.org/ (used and installed by Pyramid) -The following will be used, but the library code won't complain if not: +The following packages will be used sometimes, but the library code won't +complain much if they are absent. They include some other C-based packages, one +that is specific to Windows and won't install on other platforms, and a +selection of PDF-handling libraries where there is not a clear best choice. -- ``mmh3``: https://pypi.org/project/mmh3/ +- ``brotlipy``: https://pypi.org/project/brotlipy/ (C-based) +- ``mmh3``: https://pypi.org/project/mmh3/ (C-based) +- ``matplotlib``: https://matplotlib.org/ - ``pdfkit``: https://pypi.org/project/pdfkit/ -- ``pdfminer``: https://pypi.org/project/pdfminer/ -- ``pypiwin32``: https://pypi.org/project/pypiwin32/ -- ``pyth``: https://pyth.readthedocs.io/ -- ``python-docx`` (``import docx``): https://python-docx.readthedocs.io/ +- ``pypiwin32``: https://pypi.org/project/pypiwin32/ (Windows only) - ``weasyprint``: https://weasyprint.org/ - ``xhtml2pdf``: https://xhtml2pdf.readthedocs.io/ + +To *build* the library distribution (most people won't need this!), a few other +development libraries are required: + +- ``sphinx``: https://www.sphinx-doc.org/ +- ``sphinx_rtd_theme``: https://github.com/readthedocs/sphinx_rtd_theme +- ``twine``: https://pypi.org/project/twine/ diff --git a/setup.py b/setup.py index 29bd07b..26489c1 100644 --- a/setup.py +++ b/setup.py @@ -49,7 +49,9 @@ # - SEE ALSO external_dependencies.rst "alembic", "appdirs>=1.4.0", + "arrow>=0.15", "beautifulsoup4", # "import bs4" or "from bs4 import ..." + "chardet>=5.0.0", "colorlog", "isodate>=0.5.4", "numba", # just-in-time compilation @@ -57,6 +59,7 @@ "openpyxl", "pandas", "pendulum>=2.1.1", + "pdfminer.six>=20191010", # "import pdfminer" "prettytable", "psutil", "pygments", @@ -68,6 +71,7 @@ "semantic-version", "SQLAlchemy>=1.4,<3.0", "sqlparse", + "xlrd>=2.0.0", ] NOTES_RE_OTHER_REQUIREMENTS = """ @@ -79,45 +83,8 @@ # ----------------------------------------------------------------------------- -# The following are NOT HANDLED GRACEFULLY; their absence will cause a runtime -# ImportError, but we don't make them requirements as they need a compiler to -# install (and one might want to use the rest of the library without them). +# FOR OTHER REQUIREMENTS, AND OPTIONAL EXTRAS: SEE external_dependencies.rst # ----------------------------------------------------------------------------- -# - SEE ALSO external_dependencies.rst - -# arrow -# bcrypt -# colander -# deform -# Django>=4.2 -# dogpile.cache -# pyramid -# webob # installed by pyramid - - -# ----------------------------------------------------------------------------- -# The following are OPTIONAL; their absence will be handled gracefully, so -# they are not requirements, but we note them here: -# ----------------------------------------------------------------------------- -# - SEE ALSO external_dependencies.rst - -# mmh3 -# pdfkit -# pdfminer -# pypiwin32 -# pyth -# python-docx # "import docx" -# weasyprint -# xhtml2pdf - - -# ----------------------------------------------------------------------------- -# FOR LIBRARY DEVELOPMENT -# ----------------------------------------------------------------------------- - -# sphinx -# sphinx_rtd_theme -# twine """