Skip to content

Tags: Privex/python-helpers

Tags

3.3.0

Toggle 3.3.0's commit message
3.3.0 - Updated for Python 3.9

Author: Kale (kryogenic)

- **privex.helpers.cache**
    - Replaced `aioredis` with redis 4.2.0 (breaks Python<3.6)

3.2.1

Toggle 3.2.1's commit message
3.2.1 - adjust __init__.py for setup.py to work without deps

Due to some imports that weren't wrapped in try/except inside of `__init__.py`, the `setup.py` file was unable to function due to an ImportError raised
when trying to import the VERSION variable.

To ensure robustness when importing `privex.helpers`, all module imports inside of `privex/helpers/__init__.py` - apart from `privex.helpers.common`,
are now wrapped inside of a try/except block, ensuring at least *partial* functionality if any module fails to load for whatever reason.

Additionally, to prevent any risk of `setup.py` failing to function when no dependencies are installed, `VERSION` has been relocated to `privex.helpers.version.VERSION`,
however, `__init__.py` imports `version.VERSION` and makes it available as `VERSION`, as to not break compatibility with any existing code / systems which expect the
package version to be found inside of `__init__.py`

The `setup.py` file now only imports from privex.helpers: `extras_require` from `privex.helpers.setuppy.common` (no extra dependencies), and `VERSION` from `privex.helpers.version`

Both `privex.helpers.setuppy.commands` and `privex.helpers.settings` are still imported inside of `setup.py`, but kept within a safe try/except block, as they're not essential for
setup.py to function

3.2.0

Toggle 3.2.0's commit message
forgot to add is_adapter_async to AsyncCacheWrapper

3.1.0

Toggle 3.1.0's commit message
Downgrade SQLite upserts to 'update if exists' + add 3.9-dev to travi…

…s vers

Unfortunately, SQLite upserts (`ON CONFLICT(name) DO UPDATE xxx`) are a rather new feature (released as of SQLite 3.24.0 2018-06-04),
and it appears that the latest SQLite3 version in Ubuntu 18.04 (Bionic)'s repos is 3.22.0 - meaning that upserts are likely to be unusable
on many systems.

Due to this issue, upsert statements in `SqliteCacheManager` and `AsyncSqliteCacheManager` have been replaced with standard INSERT statements,
and the `update_cache_key` method (in both sync and async classes) now uses a standard `UPDATE` statement, which should work on all systems.

Additionally, `3.9-dev` has now been added to `.travis.yml`, but marked with `allow_failures` to avoid bugs in 3.9 (or problems with third-party libraries
that haven't yet been patched to work with 3.9) causing the travis build to fail.

3.0.0

Toggle 3.0.0's commit message
bump version from 3.0.0rc1 to 3.0.0

3.0.0rc1

Toggle 3.0.0rc1's commit message
3.0.0 - Overhaul 'net', new object cleaner, class generation/mocking …

…+ more

**Key Additions and Changes**

- `privex.helpers.common`
    - Added `strip_null` - very simple helper function to strip both `\00` and white space
      from a string - with 2 cycles for good measure.

- `privex.helpers.types`
    - Added `AUTO` / `AUTOMATIC` / `AUTO_DETECTED` dummy type, for use as the default value
      of function/method parameters, signalling to users that a parameter is auto-populated
      from another data source (e.g. instance/class attribute) if not specified.

- `privex.helpers.collections`
    - Added `copy_class_simple` (alternative to `copy_class`)
    - Added `copy_func` for copying functions, methods, and classmethods
    - Improved `_q_copy` to handle copying functions, methods and classmethods
    - Added `generate_class` + `generate_class_kw`
    - Added `Mocker.make_mock_module`
    - Added `Mocker.add_mock_modules`
    - Added `Mocker.__dir__` to track the available mock attributes and modules
    - Added `dataclasses_mock` - a `Mocker` instance which emulates `dataclasses` as a drop-in
      partially functional dummy for Python 3.6 when the `dataclasses` backport package isn't installed.
    - Various changes to `Mocker.make_mock_class` - potentially breaking, see
      the **BREAKING CHANGES** section.
    - Added `DictObject.__dir__` + `OrderedDictObject.__dir__` to enable proper tracking of dictionary keys as attributes

- `privex.helpers.net`
    - This module has now been converted into a folder-based module. Imports in `__init__.py` have been carefully
      setup to ensure that existing import statements should still work as normal
    - Added new `SocketWrapper` and `AsyncSocketWrapper` classes, which are powerful wrapper classes for working with
      Python `socket.socket` objects, including support for SSL/TLS, partial support for running socket servers, and\
      making basic HTTP requests
    - **Many, many new functions and classes!** There's too many to list, and due to the conversion into a module folder
      instead of a singular file, it's difficult to track which functions/classes are new, and which existed before.

      If you really want to know what's new, just take a look around the `privex/helpers/net` module.

- `privex.helpers.converters`
    - Added `clean_obj` - which is a function that recursively "cleans" any arbitrary object, as to make it safe to convert
      into JSON and other common serialisation formats. It supports `dict`'s, `list`'s, [attrs](https://attrs.org)
      objects, native Python `dataclass`'s, `Decimal`, and many other types of objects.
    - Added `clean_dict` (used by `clean_obj`, usually no need to call it directly)
    - Added `clean_list` (used by `clean_obj`, usually no need to call it directly)

- Added `privex.helpers.mockers` module, which contains pre-made `Mocker` objects that are designed to stand-in
  for certain libraries / classes as partially functional dummies, if the real module(s) are unavailable for whatever reason.

- **And probably some other small additions / changes**

**BREAKING CHANGES**

- Both `_copy_class_dict` and `_copy_class_slotted` now check each attribute name
  against a blacklist (default: `COPY_CLASS_BLACKLIST`), and the default blacklist
  contains `__dict__`, `__slots__` and `__weakref__`, as the first 2 can't be directly
  copied (but we copy their contents by iteration), and weakref simply can't be deep copied
  (and it probably isn't a good idea to copy it anyway).
- `_copy_class_dict` (used by `copy_class`) no longer breaks the attribute copy loop if `deep_copy=False`

- `Mocker.make_mock_class` now returns a cloned `Mocker` class or instance by default, instead of
  a barebones class / instance of a barebones class.

  This was done simply because a Mocker class/instance is designed to handle being
  instantiated with any combination of constructor arguments, and have arbitrary
  attributes be retrieved / methods called without raising errors.

  If you absolutely require a plain, simple, empty class to be generated, you may
  pass the parameter `simple=True` to generate a bare class instead of a clone of Mocker
  (similar to the old behaviour). Unlike the old version of this method, you can now specify attributes
  as a dictionary to make your barebones mock class act similar to the class it's mocking.

- Many things in `privex.helpers.net` such as `check_host` / `check_host_async` have been improved in various ways, however
  there may be some breaking changes with certain `privex.helpers.net` functions/classes in certain usecases.
    - Due to the high risk of bugs with certain networking functions that have been completely revamped, the
      older, simpler versions of various networking functions are available under `privex.helpers.net.base`
      with their original names.

      Because of the naming conflicts, to use the legacy functions/classes from `base`, you must import them
      directly from `privex.helpers.net.base` like so:

      ```
      # Option 1: import the base module itself, with an alias to prevent naming conflicts (and make it more
      # clear what you're referencing)
      from privex.helpers.net import base as netbase
      if netbase.check_host('google.com', 80):
          print('google.com is up')
      # Option 2: import the required legacy functions directly (optionally, you can alias them as needed)
      # You could also alias the newer overhauled functions while testing them in small portions
      # of your application.
      from privex.helpers.net.base import check_host
      from privex.helpers.net import check_host as new_check_host

      if check_host('www.privex.io', 443, http_test=True, use_ssl=True):
          print('[old check_host] https://www.privex.io is up')
      if new_check_host('files.privex.io', 443, http_test=True, use_ssl=True):
          print('[new check_host] https://files.privex.io is up')
      ```

2.19.0

Toggle 2.19.0's commit message
2.19.0 - Added common functions: get_return_type, typing_to_base, and…

… extract_type + a few small cleanups

2.18.0

Toggle 2.18.0's commit message
2.18.0 - Add function

2.17.1

Toggle 2.17.1's commit message
2.17.1 - Increase check_host(_async) default timeout + allow check_ho…

…st tests to fail via pytest xfail

2.17.0

Toggle 2.17.0's commit message
2.17.0 - Added net.get_host + AsyncIO versions of various net module …

…functions

**`privex.helpers.net` module**

 - Refactored `resolve_ips` to enable re-use of validation and other things between it and the AsyncIO version

 - Added `resolve_ips_async` - which is simply an AsyncIO version of `resolve_ips`
 - Added `resolve_ip_async` - again, an AsyncIO version of `resolve_ip`
 - Added `resolve_ips_multi_async` (AsyncIO `resolve_ips_multi`)
 - Added `get_rdns_async` (AsyncIO `get_rdns`)
 - Added new `check_host` function, which checks if a given service (port) on a host is up and working
 - Added `check_host_async` - same as `check_host` but uses AsyncIO