diff --git a/.appveyor.yml b/.appveyor.yml index fbcffb8..7031a8e 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,4 +1,5 @@ build: false +image: "Visual Studio 2019" environment: matrix: @@ -32,14 +33,15 @@ environment: init: - "ECHO %PYTHON% %PYTHON_VERSION% %PYTHON_ARCH%" + - "%PYTHON%/python.exe -m pip install --upgrade pip" install: - nuget install redis-64 -excludeversion - redis-64\tools\redis-server.exe --service-install - redis-64\tools\redis-server.exe --service-start - - "%PYTHON%/Scripts/pip.exe install -e ." - - "%PYTHON%/Scripts/pip.exe install -r requirements-docs.txt" - - "%PYTHON%/Scripts/pip.exe install -r requirements-pytest.txt" + - "%PYTHON%/python.exe -m pip install -e ." + - "%PYTHON%/python.exe -m pip install -r requirements-docs.txt" + - "%PYTHON%/python.exe -m pip install -r requirements-pytest.txt" test_script: - "%PYTHON%/Scripts/pytest" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..674c1f9 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,99 @@ +name: Linux + +on: [push, pull_request] + +jobs: + test_linux: + runs-on: "ubuntu-latest" + name: "Ubuntu latest - Python ${{ matrix.python-version }}" + env: + USING_COVERAGE: '3.9' + + strategy: + matrix: + python-version: ["2.7", "3.5", "3.6", "3.7", "3.8", "3.9", "pypy2"] + redis-version: [6] + + steps: + - uses: "actions/checkout@v2" + - uses: "actions/setup-python@v2" + with: + python-version: "${{ matrix.python-version }}" + - name: "Install dependencies" + run: | + set -xe + python -VV + python -m pip install --upgrade pip setuptools wheel codecov + python -m pip install -e . + python -m pip install -r requirements-pytest.txt + python -m pip install -r requirements-docs.txt + + - name: Start Redis + uses: supercharge/redis-github-action@1.2.0 + with: + redis-version: ${{ matrix.redis-version }} + + - name: "Run tests for ${{ matrix.python-version }}" + env: + CLUBLOG_APIKEY: ${{ secrets.CLUBLOG_APIKEY }} + QRZ_USERNAME: ${{ secrets.QRZ_USERNAME }} + QRZ_PWD: ${{ secrets.QRZ_PWD }} + PYTHON_VERSION: ${{ matrix.python-version }} + # delay the execution randomly by 1-20sec to reduce the + # amount of concurrent API calls on Clublog and QRZ.com + # when all CI jobs execute simultaniously + run: | + sleep $[ ( $RANDOM % 20 ) + 1 ]s + pytest --cov=./ + if [[ $PYTHON_VERSION == 3.9 ]]; then codecov; fi + if [[ $PYTHON_VERSION == 3.9 ]]; then cd docs && make html; fi + + # publish_package: + # runs-on: "ubuntu-latest" + # needs: ["test_linux"] + # if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags') + # steps: + # - name: Publish package + # uses: pypa/gh-action-pypi-publish@release/v1 + # with: + # user: __token__ + # password: ${{ secrets.PYPI_API_TOKEN }} + + # test_windows: + # runs-on: "windows-latest" + # name: "Windows latest - Python ${{ matrix.python-version }}" + # env: + # USING_COVERAGE: '3.9' + + # strategy: + # matrix: + # python-version: ["2.7", "3.5", "3.6", "3.7", "3.8", "3.9"] + # redis-version: ["6.2"] + + # steps: + # - uses: "actions/checkout@v2" + # - uses: "actions/setup-python@v2" + # with: + # python-version: "${{ matrix.python-version }}" + # - name: "Install dependencies" + # run: | + # python -VV + # python -m pip install --upgrade pip setuptools wheel codecov + # python -m pip install -e . + # python -m pip install -r requirements-pytest.txt + # python -m pip install -r requirements-docs.txt + # - name: Setup redis + # uses: shogo82148/actions-setup-redis@v1 + # with: + # redis-version: ${{ matrix.redis-version }} + # - name: "Run tests for ${{ matrix.python-version }}" + # env: + # CLUBLOG_APIKEY: ${{ secrets.CLUBLOG_APIKEY }} + # QRZ_USERNAME: ${{ secrets.QRZ_USERNAME }} + # QRZ_PWD: ${{ secrets.QRZ_PWD }} + # PYTHON_VERSION: ${{ matrix.python-version }} + # # delay the execution randomly by 1-20sec to reduce the + # # amount of concurrent API calls on Clublog and QRZ.com + # # when all CI jobs execute simultaniously + # run: | + # pytest \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index e497df3..0000000 --- a/.travis.yml +++ /dev/null @@ -1,33 +0,0 @@ -language: python -dist: xenial -python: - - "2.7" - - "3.4" - - "3.5" - - "3.6" - - "3.7" - - "3.8" - - "3.8-dev" # 3.8 development branch - - "3.9" - - "3.9-dev" # 3.8 development branch - - "nightly" - - "pypy" -jobs: - allow_failures: - - python: "nightly" -services: - - redis-server -# install dependencies -install: - - pip install -e . - - pip install -r requirements-docs.txt - - pip install -r requirements-pytest.txt - - pip install codecov -# run tests -script: - - pytest --cov=./ - - if [[ $TRAVIS_PYTHON_VERSION == 3.9 ]]; then codecov; fi - - cd docs - # build the docs on 2.7 and 3.6 (sphinx requires 2.7 or >=3.4) - - if [[ $TRAVIS_PYTHON_VERSION == 2.7 ]]; then make html; fi - - if [[ $TRAVIS_PYTHON_VERSION == 3.9 ]]; then make html; fi \ No newline at end of file diff --git a/README.md b/README.md index 00b97fa..741b20a 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ # pyhamtools -[![Build Status](https://travis-ci.com/dh1tw/pyhamtools.svg?branch=master)](https://travis-ci.com/dh1tw/pyhamtools) -[![Build status](https://ci.appveyor.com/api/projects/status/8rfgr7x6w1arixrh?svg=true)](https://ci.appveyor.com/project/dh1tw/pyhamtools) +![Build Status](https://github.com/dh1tw/pyhamtools/actions/workflows/test.yml/badge.svg) +![Build status](https://ci.appveyor.com/api/projects/status/8rfgr7x6w1arixrh/branch/master?svg=true) [![codecov](https://codecov.io/gh/dh1tw/pyhamtools/branch/master/graph/badge.svg)](https://codecov.io/gh/dh1tw/pyhamtools) [![PyPI version](https://badge.fury.io/py/pyhamtools.svg)](https://badge.fury.io/py/pyhamtools) Pyhamtools is a set of functions and classes for Amateur Radio purpose. -Currently the core part is the Callsign Lookup which decodes any amateur radio +Currently, the core part is the Callsign Lookup which decodes any amateur radio callsign string and provides the corresponding information (Country, DXCC entity, CQ Zone...etc). This basic functionality is needed for Logbooks, DX-Clusters or Log Checking. This and additional convenience features are @@ -22,8 +22,8 @@ Currently, * [eQSL.cc user list](https://www.eqsl.cc) * [Clublog & OQRS user list](http://clublog.freshdesk.com/support/solutions/articles/3000064883-list-of-club-log-and-lotw-users) -Other modules include location based calculations (e.g. distance, -heading between Maidenhead locators) or frequency based calculations +Other modules include location-based calculations (e.g. distance, +heading between Maidenhead locators) or frequency-based calculations (e.g. frequency to band). ## References @@ -33,16 +33,17 @@ This Library is used in production at the [DXHeat.com DX Cluster](https://dxheat ## Compatibility Pyhamtools is since version 0.6.0 compatible with > Python 2.7 and > python 3.3. -We check compatibility on OSX, Windows and Linux with the following Python +We check compatibility on OSX, Windows, and Linux with the following Python versions: * Python 2.7 -* Python 3.4 -* Python 3.5 +* Python 3.4 (will be deprecated in 2022) +* Python 3.5 (will be deprecated in 2022) * Python 3.6 * Python 3.7 * Python 3.8 -* [pypy](https://pypy.org/) (Python 2) +* Python 3.9 +* [pypy2](https://pypy.org/) (Python 2) ## Documentation @@ -56,7 +57,7 @@ Open Source Software licenses, including the MIT license at [choosealicense.com] ## Installation -Easiest way to install pyhamtools is through the packet manager `pip`: +The easiest way to install pyhamtools is through the packet manager `pip`: ```bash @@ -92,11 +93,11 @@ $ pip install pyhamtools ## Testing An extensive set of unit tests has been created for all Classes & Methods. -In order to be able to perform all tests you need a QRZ.com account and a +To be able to perform all tests, you need a QRZ.com account and a [Clublog API key](http://clublog.freshdesk.com/support/solutions/articles/54910-api-keys). pyhamtools rely on the [pytest](https://docs.pytest.org/en/latest/) testing -framework. In order to install it with all the needed dependencies run: +framework. To install it with all the needed dependencies run: ```bash @@ -104,7 +105,7 @@ $ pip install -r requirements-pytest.txt ``` -The QRZ.com credentials and the Clublog API key have to be set in environment +The QRZ.com credentials and the Clublog API key have to be set in the environment variables: ```bash @@ -115,8 +116,8 @@ $ export QRZ_PWD="" ``` -In order to perform the tests related to the [redis](https://redis.io/) key/value -store, a redis server has to be up & running. +To perform the tests related to the [redis](https://redis.io/) key/value +store, a Redis server has to be up & running. ```bash diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst index ade2100..f587d59 100644 --- a/docs/source/changelog.rst +++ b/docs/source/changelog.rst @@ -1,6 +1,15 @@ Changelog --------- +PyHamTools 0.7.7 +================ + +01. June 2021 + +* Added support for Python 3.9 +* Added deprecation warnings for Python 3.4 and 3.5 + + PyHamTools 0.7.6 ================ diff --git a/pyhamtools/lookuplib.py b/pyhamtools/lookuplib.py index 3950d41..b4c6134 100644 --- a/pyhamtools/lookuplib.py +++ b/pyhamtools/lookuplib.py @@ -1426,9 +1426,13 @@ class LookupLib(object): mapping = None with open(country_mapping_filename, "r") as f: - mapping = json.loads(f.read(),encoding='UTF-8') + mapping = json.loads(f.read()) - cty_list = plistlib.readPlist(cty_file) + with open(cty_file, 'rb') as f: + try: + cty_list = plistlib.load(f) #New API (Python >=3.4) + except AttributeError: + cty_list = plistlib.readPlist(cty_file) #Old API (Python >=2.7 && <=3.8) for item in cty_list: entry = {} @@ -1514,7 +1518,7 @@ class LookupLib(object): Deserialize a JSON into a dictionary """ - my_dict = json.loads(json_data.decode('utf8'), encoding='UTF-8') + my_dict = json.loads(json_data.decode('utf8')) for item in my_dict: if item == const.ADIF: diff --git a/pyhamtools/qsl.py b/pyhamtools/qsl.py index ada2e26..d6df1f4 100644 --- a/pyhamtools/qsl.py +++ b/pyhamtools/qsl.py @@ -121,7 +121,7 @@ def get_clublog_users(**kwargs): files = zip_file.namelist() cl_json_unzipped = zip_file.read(files[0]).decode('utf8').replace("'", '"') - cl_data = json.loads(cl_json_unzipped, encoding='UTF-8') + cl_data = json.loads(cl_json_unzipped) error_count = 0 @@ -203,4 +203,4 @@ def get_eqsl_users(**kwargs): else: raise IOError("HTTP Error: " + str(result.status_code)) - return eqsl \ No newline at end of file + return eqsl diff --git a/pyhamtools/version.py b/pyhamtools/version.py index 0a57b1a..45ebe53 100644 --- a/pyhamtools/version.py +++ b/pyhamtools/version.py @@ -1,3 +1,3 @@ -VERSION = (0, 7, 6) +VERSION = (0, 7, 7) __release__ = ''.join(['-.'[type(x) == int]+str(x) for x in VERSION])[1:] __version__ = '.'.join((str(VERSION[0]), str(VERSION[1]))) diff --git a/requirements-pytest.txt b/requirements-pytest.txt index efc6cc0..ff56c01 100644 --- a/requirements-pytest.txt +++ b/requirements-pytest.txt @@ -1,4 +1,5 @@ -pytest>=3.3.2 +pytest>=6.2.2; python_version>='3.6' +pytest==4.6.11; python_version<='3.5' and python_version>='2.7' pytest-blockage>=0.2.2 -pytest-localserver>=0.5.0 -pytest-cov>=2.7.1 +pytest-localserver>=0.5 +pytest-cov>=2.12 diff --git a/test/test_lookuplib.py b/test/test_lookuplib.py index a67af60..f138ce6 100644 --- a/test/test_lookuplib.py +++ b/test/test_lookuplib.py @@ -42,4 +42,4 @@ class TestlookupLibHelper: fixClublogApi._generate_random_word() assert type(fixClublogApi._generate_random_word(5)) is unicode - assert len(fixClublogApi._generate_random_word(5)) is 5 + assert len(fixClublogApi._generate_random_word(5)) == 5