Skip to content
Permalink
Browse files

Merge pull request #156 from mshriver/py3-only-gtfo

Update python supported versions
  • Loading branch information
mshriver committed Aug 28, 2019
2 parents 2bca6bf + 611c443 commit 19b587aeaa3a530fdbb09997513df6feaebf4b01
@@ -4,15 +4,12 @@ dist: xenial
addons:
firefox: latest-esr
python:
- '2.7'
- '3.5'
- '3.6'
- '3.7'
- pypy
- 'pypy3.5'
stages:
- test
- name: deploy
if: tag IS true
jobs:
include:
- stage: deploy
@@ -24,6 +21,7 @@ jobs:
deploy:
provider: pypi
skip_existing: true
# Ievgen
user: ghislieri
distributions: sdist bdist_wheel
password:
@@ -1,3 +1,40 @@
[wheel]
universal=1
[metadata]
name = widgetastic.core
author = Milan Falesnik
author_email = mfalesni@redhat.com
maintainer = Pete Savage
maintainer_email = psavage@redhat.com
description = Making testing of UIs fantastic
long_description= file: README.rst
license = Apache license
url = https://github.com/RedHatQE/widgetastic.core
classifiers =
License :: OSI Approved :: Apache Software License
Programming Language :: Python
Programming Language :: Python :: 3
Programming Language :: Python :: 3.5
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
Programming Language :: Python :: Implementation :: CPython
Programming Language :: Python :: Implementation :: PyPy
Topic :: Software Development :: Libraries :: Python Modules
Topic :: Software Development :: Quality Assurance
Topic :: Software Development :: Testing

[options]
install_requires =
anytree
cached_property
jsmin
pytest
selenium
selenium-smart-locator
wait_for
setup_requires = setuptools_scm
package_dir =
=src
packages = find:

[options.packages.find]
where = src

@@ -1,47 +1,7 @@
# -*- coding: utf-8 -*-
import codecs
from setuptools import find_packages, setup


setup(
name="widgetastic.core",
use_scm_version=True,
author="Milan Falesnik",
author_email="mfalesni@redhat.com",
description='Making testing of UIs fantastic',
long_description=codecs.open('README.rst', mode='r', encoding='utf-8').read(),
license="Apache license",
url="https://github.com/RedHatQE/widgetastic.core",
packages=find_packages('src'),
package_dir={'': 'src'},
install_requires=[
'anytree',
'cached_property',
'jsmin',
'pytest',
'selenium',
'selenium-smart-locator',
'six',
'wait_for',
],
setup_requires=[
'setuptools_scm',
],
classifiers=[
'License :: OSI Approved :: Apache Software License',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'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',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Topic :: Software Development :: Libraries :: Python Modules',
'Topic :: Software Development :: Quality Assurance',
'Topic :: Software Development :: Testing',
],
)
@@ -1,2 +1 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
@@ -1,8 +1,5 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

import inspect
import six
from cached_property import cached_property
from collections import namedtuple
from jsmin import jsmin
@@ -671,7 +668,7 @@ def send_keys(self, text, locator, *args, **kwargs):
*args: See :py:meth:`elements`
**kwargs: See :py:meth:`elements`
"""
text = six.text_type(text) or ''
text = str(text) or ''
file_intercept = False
# If the element is input type file, we will need to use the file detector
if self.tag(locator, *args, **kwargs) == 'input':
@@ -863,7 +860,7 @@ def __getattr__(self, attr):
"""
value = getattr(self._browser, attr)
if inspect.ismethod(value):
function = six.get_method_function(value)
function = value.__func__
# Bind the function like it was defined on this class
value = function.__get__(self, BrowserParentWrapper)
return value
@@ -1,6 +1,4 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from selenium.common.exceptions import ( # NOQA
NoSuchElementException, MoveTargetOutOfBoundsException, StaleElementReferenceException, # NOQA
NoAlertPresentException, UnexpectedAlertPresentException, WebDriverException) # NOQA
@@ -1,9 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

import functools
import logging
import time
from six import wraps, get_method_function, get_method_self

from .exceptions import DoNotReadThisWidget

@@ -108,7 +106,7 @@ def logged(log_args=False, log_result=False):
log_result: Whether to log the result value returned from the method.
"""
def g(f):
@wraps(f)
@functools.wraps(f)
def wrapped(self, *args, **kwargs):
start_time = time.time()
signature = f.__name__ + (call_sig(args, kwargs) if log_args else '')
@@ -158,6 +156,6 @@ def call_unlogged(method, *args, **kwargs):
try:
f = method.original_function
except AttributeError:
f = get_method_function(method)
f = method.__func__

return f(get_method_self(method), *args, **kwargs)
return f(method.__self__, *args, **kwargs)
@@ -1,13 +1,10 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
"""This module contains some supporting classes."""

import functools
import re
import six
import string
import time
from cached_property import cached_property
from six import wraps
from smartloc import Locator
from threading import Lock
from selenium.common.exceptions import StaleElementReferenceException
@@ -525,7 +522,7 @@ def nested_getattr(o, steps):
Returns:
The value of required attribute.
"""
if isinstance(steps, six.string_types):
if isinstance(steps, str):
steps = steps.split('.')
if not isinstance(steps, (list, tuple)):
raise TypeError(
@@ -566,8 +563,8 @@ def deflatten_dict(d):
A dictionary.
"""
current_dict = {}
for key, value in six.iteritems(d):
if not isinstance(key, six.string_types):
for key, value in d.items():
if not isinstance(key, str):
current_dict[key] = value
continue
local_dict = current_dict
@@ -674,7 +671,7 @@ def retry_stale_element(method):
to work with it. There is no 100% robust solution to check that all JS are over on some page.
"""

@wraps(method)
@functools.wraps(method)
def wrap(*args, **kwargs):
attempts = 10
for _ in range(attempts):
@@ -1,6 +1,4 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

"""This module contains the base classes that are used to implement the more specific behaviour."""
from .base import * # noqa: F403 F401
from .checkbox import Checkbox # noqa: F401
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
import functools
import inspect
import six
import types
from copy import copy

@@ -25,7 +25,7 @@ def do_not_read_this_widget():

def wrap_fill_method(method):
"""Generates a method that automatically coerces the first argument as Fillable."""
@six.wraps(method)
@functools.wraps(method)
def wrapped(self, value, *args, **kwargs):
return method(self, Fillable.coerce(value), *args, **kwargs)

@@ -34,7 +34,7 @@ def wrapped(self, value, *args, **kwargs):

def resolve_verpicks_in_method(method):
"""Generates a method that automatically resolves VersionPick attributes"""
@six.wraps(method)
@functools.wraps(method)
def wrapped(self, *args, **kwargs):
def resolve_arg(parent, arg):
if (isinstance(arg, ConstructorResolvable) and not (
@@ -149,7 +149,7 @@ def __init__(self, widget):

@property
def _extra_objects_list(self):
return list(six.iterkeys(self._widget.browser.extra_objects))
return list(self._widget.browser.extra_objects)

def __dir__(self):
return self._extra_objects_list
@@ -206,15 +206,15 @@ def __new__(cls, name, bases, attrs):
desc_name_mapping = {}
included_widgets = []
for base in bases:
for key, value in six.iteritems(getattr(base, '_desc_name_mapping', {})):
for key, value in getattr(base, '_desc_name_mapping', {}).items():
desc_name_mapping[key] = value
for widget_includer in getattr(base, '_included_widgets', ()):
included_widgets.append(widget_includer)
for widget_name in widget_includer.widget_class.cls_widget_names():
new_attrs[widget_name] = IncludedWidget(widget_includer._seq_id, widget_name,
widget_includer.use_parent)

for key, value in six.iteritems(attrs):
for key, value in attrs.items():
if inspect.isclass(value) and issubclass(value, View):
new_attrs[key] = WidgetDescriptor(value)
desc_name_mapping[new_attrs[key]] = key
@@ -255,7 +255,7 @@ def __new__(cls, name, bases, attrs):
return super(WidgetMetaclass, cls).__new__(cls, name, bases, new_attrs)


class Widget(six.with_metaclass(WidgetMetaclass, object)):
class Widget(object, metaclass=WidgetMetaclass):
"""Base class for all UI objects.
Does couple of things:
@@ -564,7 +564,7 @@ def _process_fill_handler(self, handler):
A 2-tuple consisting of ``(action_callable, obj_for_repr)``. The ``obj_for_repr`` is an
object that can be passed to a logger that uses ``%r``.
"""
if isinstance(handler, six.string_types):
if isinstance(handler, str):
try:
handler = getattr(self, handler)
except AttributeError:
@@ -685,7 +685,7 @@ def __repr__(self):
return '{}({!r})'.format(type(self).__name__, self.locator)


class WTMixin(six.with_metaclass(WidgetMetaclass, object)):
class WTMixin(object, metaclass=WidgetMetaclass):
"""Base class for mixins for views.
Lightweight class that only has the bare minimum of what is required for widgetastic operation.
@@ -1,10 +1,9 @@
# -*- coding: utf-8 -*-
import six
from collections import namedtuple

from cached_property import cached_property
from jsmin import jsmin
from six.moves import html_parser
from html.parser import HTMLParser

from widgetastic.utils import normalize_space
from .base import Widget
@@ -119,15 +118,15 @@ def all_options(self):
"""
# More reliable using javascript
options = self.browser.execute_script(self.ALL_OPTIONS, self.browser.element(self))
parser = html_parser.HTMLParser()
parser = HTMLParser()
return [
self.Option(normalize_space(parser.unescape(option[0])), option[1])
for option in options]

@property
def all_selected_options(self):
"""Returns a list of all selected options as their displayed texts."""
parser = html_parser.HTMLParser()
parser = HTMLParser()
return [
normalize_space(parser.unescape(option))
for option
@@ -261,7 +260,7 @@ def fill(self, item_or_items):
if isinstance(item, tuple):
try:
mod, value = item
if not isinstance(mod, six.string_types):
if not isinstance(mod, str):
raise ValueError('The select modifier must be a string')
mod = mod.lower()
except ValueError:

0 comments on commit 19b587a

Please sign in to comment.
You can’t perform that action at this time.