Skip to content

Commit

Permalink
feat: remove python 2.7 support (#227)
Browse files Browse the repository at this point in the history
* feat: remove python 2.7 support

* fix: remove more python 2.7 imports

* fix: remove typing import, not needed in Py3
  • Loading branch information
rgonalo committed Mar 28, 2021
1 parent 7f5e862 commit 27cfc10
Show file tree
Hide file tree
Showing 18 changed files with 65 additions and 155 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [2.7, 3.5, 3.6, 3.7, 3.8, 3.9]
python-version: [3.5, 3.6, 3.7, 3.8, 3.9]
fail-fast: false

steps:
Expand All @@ -32,7 +32,6 @@ jobs:
run: |
coverage run --source=toolium -m pytest toolium/test
- name: Publish on coveralls.io
if: ${{ matrix.python-version != '2.7' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COVERALLS_FLAG_NAME: Python ${{ matrix.python-version }}
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ v2.0.0

*Release date: In development*

- Remove Python 2.7, 3.3 and 3.4 support
- Update deprecated methods to fix warnings in python3 execution
- Move *get_valid_filename* and *makedirs_safe* methods from *toolium.path_utils* to *toolium.utils.path_utils*
- Move *Utils* class from *toolium.utils* to *toolium.utils.driver_utils*
Expand Down
96 changes: 30 additions & 66 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,41 +1,23 @@
APP = toolium
VERSION ?= $(shell cat VERSION)
RELEASE ?= $(shell git log --pretty=oneline | wc -l | tr -d ' ')
ARCH = noarch
PACKAGE = $(APP)-$(VERSION)-$(RELEASE).$(ARCH).rpm
ROOT = $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
MKD2PDF ?= $(shell which markdown-pdf)
VIRTUALENV ?= virtualenv
TEST = tests
ROOT = $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
SPHINXBUILD = sphinx-build
SPHINXSOURCEDIR = docs
SPHINXBUILDDIR = docs/build
TMP = $(ROOT)/tmp
VENV_PREFIX = $(TMP)/.venv
VENV = $(VENV_PREFIX)/$(APP)
REQ = requirements.txt
TESTREQ = requirements_dev.txt

ifeq ($(OS),Windows_NT)
BIN = Scripts
LIB = Lib
TGZ_EXT = zip
PYTHON ?= $(shell which python).exe
PYTHON_EXE ?= $(shell where python | head -n1)
else
BIN = bin
LIB = lib/python2.7
TGZ_EXT = tar.gz
PYTHON ?= $(shell which python2.7)
PYTHON_EXE = python2.7
endif

TMP=$(ROOT)/tmp
VENV_PREFIX = $(TMP)/.venv
VENV = $(VENV_PREFIX)/$(APP)
REQ = requirements.txt

TESTREQ = requirements_dev.txt

COVERAGE_ARGS=--with-coverage --cover-erase --cover-package=$(APP) \
--cover-branches --cover-xml \
--cover-xml-file=$(ROOT)/dist/coverage.xml

all: default

default:
Expand All @@ -49,7 +31,6 @@ default:
@echo " venv - Create and update virtual environments"
@echo " install - Install application"
@echo " sdist - Build a tar.gz software distribution of the package"
# @echo " rpm - Create $(PACKAGE) rpm"
@echo " egg - Create python egg"
@echo " unittest - Execute unit tests"
@echo " doc - Build sphinx documentation"
Expand All @@ -58,68 +39,51 @@ default:

init:
mkdir -p $(ROOT)/dist
# mkdir -p $(TMP)/rpmbuild/SOURCES
# mkdir -p $(TMP)/rpmbuild/BUILD
# mkdir -p $(TMP)/rpmbuild/RPMS

sdist: init venv
@echo ">>> Creating source distribution..."
$(VENV)/$(BIN)/python setup.py sdist
@echo ">>> OK. TGZ generated in $(ROOT)/dist"
@echo

disabled-rpm: init sdist
@echo ">>> Creating RPM package..."
cp $(ROOT)/dist/$(APP)-$(VERSION).${TGZ_EXT} $(TMP)/rpmbuild/SOURCES
rpmbuild -bb $(APP).spec \
--define "version $(VERSION)" \
--define "release $(RELEASE)" \
--define "arch $(ARCH)" \
--define "_target_os linux" \
--define "_topdir $(TMP)/rpmbuild" \
--define "buildroot $(TMP)/rpmbuild/BUILDROOT" \
--define "__python $(PYTHON)" \
--define "python_sitelib $(VENV)/$(LIB)/site-packages" \
--define "_sysconfdir /etc" \
--define "_bindir /usr/bin" \
--nodeps \
--buildroot=$(TMP)/rpmbuild/BUILDROOT

cp $(TMP)/rpmbuild/RPMS/$(ARCH)/$(PACKAGE) $(ROOT)/dist
@echo ">>> OK. RPM generated in $(ROOT)/dist"
@echo

venv: $(VENV)

$(VENV): $(REQ) $(TESTREQ)
mkdir -p $@; \
export GIT_SSL_NO_VERIFY=true; \
$(VIRTUALENV) --no-site-packages --distribute -p $(PYTHON) $@; \
$@/$(BIN)/pip install --upgrade -r $(REQ); \
$@/$(BIN)/pip install --upgrade -r $(TESTREQ); \
$(PYTHON_EXE) -m venv $@; \
source $(VENV)/$(BIN)/activate; \
python -m pip install --upgrade -r $(REQ); \
python -m pip install --upgrade -r $(TESTREQ);

sdist: init venv
@echo ">>> Creating source distribution..."
source $(VENV)/$(BIN)/activate; \
python setup.py sdist
@echo ">>> OK. TGZ generated in $(ROOT)/dist"
@echo

unittest: init venv
$(VENV)/$(BIN)/pytest toolium/test
source $(VENV)/$(BIN)/activate; \
python -m pytest toolium/test

coverage: init venv
$(VENV)/$(BIN)/nosetests $(COVERAGE_ARGS) $(UNIT_TEST_ARGS)
source $(VENV)/$(BIN)/activate; \
coverage run --source=toolium -m pytest toolium/test
@echo ">>> OK. Coverage reports generated in $(ROOT)/dist"

# Just for development purposes. It uses your active python2.7
# Just for development purposes
# Remember to update your requirements if needed
egg:
$(PYTHON_EXE) setup.py bdist_egg
python -m pip install setuptools; \
python setup.py bdist_egg

# Just for development purposes. It uses your active python2.7
# Just for development purposes
# Remember to update your requirements if needed
install:
$(PYTHON_EXE) setup.py install
python -m pip install setuptools; \
python setup.py install

doc: venv
doc: init venv
@echo ">>> Cleaning sphinx doc files..."
rm -rf $(SPHINXBUILDDIR)/html
@echo ">>> Generating doc files..."
$(VENV)/$(BIN)/$(SPHINXBUILD) -b html $(SPHINXSOURCEDIR) $(SPHINXBUILDDIR)/html
source $(VENV)/$(BIN)/activate; \
$(SPHINXBUILD) -b html $(SPHINXSOURCEDIR) $(SPHINXBUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(SPHINXBUILDDIR)/html."

Expand Down
5 changes: 1 addition & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,8 @@ pattern and includes a simple visual testing solution.
Getting Started
---------------

The requirements to install Toolium are `Python 2.7 or 3.3+ <http://www.python.org>`_ and
`pip <https://pypi.org/project/pip>`_. If you use Python 2.7.9+, you don't need to install pip separately.

Run ``pip install toolium`` to install the latest version from `PyPi <https://pypi.org/project/toolium>`_. It's
highly recommendable to use a virtualenv.
highly recommendable to use a virtualenv. The minimal python version to use Toolium is `Python 3.5 <http://www.python.org>`_.

The main dependencies are:

Expand Down
6 changes: 2 additions & 4 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
requests>=2.12.4 # api tests
requests>=2.12.4,<3 # api tests
selenium>=2.53.6,<4 # web tests
Appium-Python-Client>=0.24,<1 # mobile tests
six>=1.10.0
screeninfo==0.3.1
typing==3.7.4.1
lxml==4.6.2
lxml==4.*
8 changes: 3 additions & 5 deletions requirements_dev.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
Sphinx==1.8.5 ; python_version < '3.0'
Sphinx==3.* ; python_version >= '3.5'
Sphinx==3.*
lettuce==0.2.23
pytest==4.6.11 ; python_version < '3.0'
pytest==6.* ; python_version >= '3.5'
pytest==6.*
coverage==5.*
coveralls==3.* ; python_version >= '3.5'
coveralls==3.*
mock==3.*
requests-mock==1.*
needle==0.5.0
Expand Down
3 changes: 0 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,6 @@ def get_long_description():
'License :: OSI Approved :: Apache Software License',
'Natural Language :: English',
'Operating System :: OS Independent',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
Expand Down
3 changes: 1 addition & 2 deletions toolium/config_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,11 @@
import ast
import logging
import os

from appium import webdriver as appiumdriver
from configparser import NoSectionError
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.firefox.options import Options
from six.moves.configparser import NoSectionError # Python 2 and 3 compatibility

from toolium.driver_wrappers_pool import DriverWrappersPool

Expand Down
17 changes: 6 additions & 11 deletions toolium/config_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
"""

import logging
from configparser import ConfigParser, NoSectionError, NoOptionError
from io import StringIO

from six.moves import configparser, StringIO # Python 2 and 3 compatibility


class ExtendedConfigParser(configparser.ConfigParser):
class ExtendedConfigParser(ConfigParser):
def optionxform(self, optionstr):
"""Override default optionxform in ConfigParser"""
return optionstr
Expand All @@ -37,7 +37,7 @@ def get_optional(self, section, option, default=None):
"""
try:
return self.get(section, option)
except (configparser.NoSectionError, configparser.NoOptionError):
except (NoSectionError, NoOptionError):
return default

def getboolean_optional(self, section, option, default=False):
Expand All @@ -51,7 +51,7 @@ def getboolean_optional(self, section, option, default=False):
"""
try:
return self.getboolean(section, option)
except (configparser.NoSectionError, configparser.NoOptionError):
except (NoSectionError, NoOptionError):
return default

def deepcopy(self):
Expand All @@ -68,12 +68,7 @@ def deepcopy(self):

# Create a new config object
config_copy = ExtendedConfigParser()
try:
# Python 3
config_copy.read_file(config_string)
except AttributeError:
# Python 2.7
config_copy.readfp(config_string)
config_copy.read_file(config_string)

return config_copy

Expand Down
3 changes: 1 addition & 2 deletions toolium/pageelements/page_elements.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,7 @@ def web_elements(self):
return self._web_elements

@property
def page_elements(self):
# type: () -> List[Any]
def page_elements(self) -> List[Any]:
"""Find multiple PageElement using element locator
:returns: list of page element objects
Expand Down
7 changes: 1 addition & 6 deletions toolium/test/test_jira.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,7 @@ def test_change_jira_status_attachments(logger):
body_bytes = req_mock.last_request.body

# Check requested url
try:
# Python 3
body = "".join(map(chr, body_bytes))
except TypeError:
# Python 2.7
body = body_bytes
body = "".join(map(chr, body_bytes))
for partial_url in ['"jiraStatus"\r\n\r\nPass', '"jiraTestCaseId"\r\n\r\nTOOLIUM-1',
'"summaryPrefix"\r\n\r\nprefix', '"labels"\r\n\r\nlabel1 label2',
'"comments"\r\n\r\ncomment', '"version"\r\n\r\nRelease 1.0', '"build"\r\n\r\n453',
Expand Down
8 changes: 2 additions & 6 deletions toolium/test/utils/test_path_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,11 @@
"""

import os
try:
import Queue as queue # Py2
except ImportError:
import queue as queue # Py3
import pytest
import queue as queue
import threading
import uuid

import pytest

from toolium.utils.path_utils import get_valid_filename, makedirs_safe

filename_tests = (
Expand Down
16 changes: 2 additions & 14 deletions toolium/test_cases.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
"""

import logging
import sys
import unittest

from toolium.config_driver import get_error_message_from_exception
Expand Down Expand Up @@ -65,19 +64,8 @@ def setUp(self):

def tearDown(self):
# Get unit test exception
py2_exception = sys.exc_info()[1]
try:
# Python 3.4+
exception_info = self._outcome.errors[-1][1] if len(self._outcome.errors) > 0 else None
exception = exception_info[1] if exception_info else None
except AttributeError:
try:
# Python 3.3
exceptions_list = self._outcomeForDoCleanups.failures + self._outcomeForDoCleanups.errors
exception = exceptions_list[0][1] if exceptions_list else None
except AttributeError:
# Python 2.7
exception = py2_exception
exception_info = self._outcome.errors[-1][1] if len(self._outcome.errors) > 0 else None
exception = exception_info[1] if exception_info else None

if not exception:
self._test_passed = True
Expand Down
9 changes: 3 additions & 6 deletions toolium/utils/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@
import datetime
import logging

from six import string_types
from six.moves import xrange

logger = logging.getLogger(__name__)


Expand All @@ -49,7 +46,7 @@ def replace_param(param, language='es'):
:param language: language to configure date format for NOW and TODAY
:return: data with the correct replacements
"""
if not isinstance(param, string_types):
if not isinstance(param, str):
return param

new_param, is_replaced = _replace_param_type(param)
Expand Down Expand Up @@ -179,11 +176,11 @@ def _replace_param_fixed_length(param):
if any(x in param for x in ['STRING_ARRAY_WITH_LENGTH_', 'INTEGER_ARRAY_WITH_LENGTH_']):
seeds = {'STRING': 'a', 'INTEGER': 1}
seed, length = param[1:-1].split('_ARRAY_WITH_LENGTH_')
new_param = list(seeds[seed] for x in xrange(int(length)))
new_param = list(seeds[seed] for x in range(int(length)))
is_replaced = True
elif 'JSON_WITH_LENGTH_' in param:
length = int(param[1:-1].split('JSON_WITH_LENGTH_')[1])
new_param = dict((str(x), str(x)) for x in xrange(length))
new_param = dict((str(x), str(x)) for x in range(length))
is_replaced = True
elif any(x in param for x in ['STRING_WITH_LENGTH_', 'INTEGER_WITH_LENGTH_']):
seeds = {'STRING': 'a', 'INTEGER': '1'}
Expand Down

0 comments on commit 27cfc10

Please sign in to comment.