Skip to content

Commit

Permalink
Drop Python 2 support
Browse files Browse the repository at this point in the history
  • Loading branch information
dralley committed Dec 1, 2021
1 parent cd50896 commit 84a559d
Show file tree
Hide file tree
Showing 25 changed files with 91 additions and 192 deletions.
2 changes: 0 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
language: python
matrix:
include:
- python: "2.7"
env: TOXENV=py27
- python: "3.6"
env: TOXENV=py36
- python: "3.7"
Expand Down
7 changes: 0 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,6 @@ http://productmd.readthedocs.io/en/latest/
Building
--------

### Build requires

* Six: Python 2 and 3 Compatibility Library
* `pip install six`
* Fedora: `dnf install python-six python3-six`


### Build

To see all options run:
Expand Down
2 changes: 0 additions & 2 deletions productmd/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-

# Copyright (C) 2015 Red Hat, Inc.
#
# This library is free software; you can redistribute it and/or
Expand Down
30 changes: 15 additions & 15 deletions productmd/common.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# pylint: disable=super-on-old-class


Expand Down Expand Up @@ -33,10 +32,11 @@
import contextlib
import ssl
import warnings
import urllib
import http.client

import six
from six.moves.configparser import ConfigParser

from configparser import ConfigParser
from io import StringIO

VERSION = (1, 2)

Expand Down Expand Up @@ -165,7 +165,7 @@ def _urlopen(path):
# Older Python versions (<2.7.9) do not support it. In those cases the
# ssl module will not have the method to create the context.
kwargs['context'] = ssl._create_unverified_context()
return six.moves.urllib.request.urlopen(path, **kwargs)
return urllib.request.urlopen(path, **kwargs)


@contextlib.contextmanager
Expand All @@ -178,7 +178,7 @@ def open_file_obj(f, mode="r"):
:param mode: how to open the file
:type mode: string
"""
if isinstance(f, six.string_types):
if isinstance(f, str):
if f.startswith(("http://", "https://", "ftp://")):
file_obj = _urlopen(f)
yield file_obj
Expand All @@ -195,13 +195,13 @@ def _file_exists(path):
try:
file_obj = _urlopen(path)
file_obj.close()
except six.moves.urllib.error.HTTPError:
except urllib.error.HTTPError:
return False
return True
return os.path.exists(path)


class MetadataBase(object):
class MetadataBase:
def _assert_type(self, field, expected_types):
value = getattr(self, field)
for atype in expected_types:
Expand Down Expand Up @@ -269,7 +269,7 @@ def loads(self, s):
:param s: input data
:type s: str
"""
io = six.StringIO()
io = StringIO()
io.write(s)
io.seek(0)
self.load(io)
Expand All @@ -294,7 +294,7 @@ def dumps(self):
:rtype: str
"""
io = six.StringIO()
io = StringIO()
self.dump(io)
io.seek(0)
return io.read()
Expand All @@ -306,7 +306,7 @@ def parse_file(self, f):
f.seek(0)
elif hasattr(f, "seek"):
f.seek(0)
if six.PY3 and isinstance(f, six.moves.http_client.HTTPResponse):
if isinstance(f, http.client.HTTPResponse):
# HTTPResponse needs special handling in py3
reader = codecs.getreader("utf-8")
parser = json.load(reader(f))
Expand All @@ -316,7 +316,7 @@ def parse_file(self, f):

def build_file(self, parser, f):
# build file from parser or dict with data
json.dump(parser, f, indent=4, sort_keys=True, separators = (",", ": "))
json.dump(parser, f, indent=4, sort_keys=True, separators=(",", ": "))

def deserialize(self, parser):
# copy data from parser to instance
Expand All @@ -343,7 +343,7 @@ def __init__(self, parent, metadata_type):
self.metadata_type = metadata_type

def _validate_version(self):
self._assert_type("version", six.string_types)
self._assert_type("version", [str])
self._assert_matches_re("version", [r"^\d+\.\d+$"])

@property
Expand Down Expand Up @@ -550,7 +550,7 @@ def __init__(self, *args, **kwargs):
ConfigParser.__init__(self, *args, **kwargs)
else:
kwargs["dict_type"] = SortedDict
super(SortedConfigParser, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self.seen = set()

def optionxform(self, optionstr):
Expand All @@ -566,4 +566,4 @@ def option_lookup(self, section_option_list, default=None):
def read_file(self, *args, **kwargs):
if sys.version_info[0] == 2:
return self.readfp(*args, **kwargs)
return super(SortedConfigParser, self).read_file(*args, **kwargs)
return super().read_file(*args, **kwargs)
5 changes: 1 addition & 4 deletions productmd/compose.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-


# Copyright (C) 2015 Red Hat, Inc.
#
# This library is free software; you can redistribute it and/or
Expand Down Expand Up @@ -49,7 +46,7 @@
)


class Compose(object):
class Compose:
"""
This class provides easy access to compose metadata.
Expand Down
49 changes: 22 additions & 27 deletions productmd/composeinfo.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-


# Copyright (C) 2015 Red Hat, Inc.
#
# This library is free software; you can redistribute it and/or
Expand Down Expand Up @@ -36,8 +33,6 @@
import productmd.common
from productmd.common import Header, RELEASE_VERSION_RE

import six


__all__ = (
"ComposeInfo",
Expand All @@ -47,9 +42,8 @@
)


if six.PY3:
def cmp(a, b):
return (a > b) - (a < b)
def cmp(a, b):
return (a > b) - (a < b)


# order matters - used in __cmp__
Expand Down Expand Up @@ -121,7 +115,7 @@ class ComposeInfo(productmd.common.MetadataBase):
"""

def __init__(self):
super(ComposeInfo, self).__init__()
super().__init__()

self.header = Header(self, "productmd.composeinfo") #: (:class:`.Header`) -- Metadata header
self.compose = Compose(self) #: (:class:`.Compose`) -- Compose details
Expand Down Expand Up @@ -265,7 +259,7 @@ class Compose(productmd.common.MetadataBase):
"""

def __init__(self, metadata):
super(Compose, self).__init__()
super().__init__()
self._section = "compose"
self._metadata = metadata
self.id = None
Expand Down Expand Up @@ -293,22 +287,22 @@ def __cmp__(self, other):
return 0

def _validate_id(self):
self._assert_type("id", list(six.string_types))
self._assert_type("id", [str])
self._assert_not_blank("id")
self._assert_matches_re("id", [r".*\d{8}(\.nightly|\.n|\.ci|\.test|\.t)?(\.\d+)?"])

def _validate_date(self):
self._assert_type("date", list(six.string_types))
self._assert_type("date", [str])
self._assert_matches_re("date", [r"^\d{8}$"])

def _validate_type(self):
self._assert_value("type", COMPOSE_TYPES)

def _validate_respin(self):
self._assert_type("respin", list(six.integer_types))
self._assert_type("respin", [int])

def _validate_label(self):
self._assert_type("label", [type(None)] + list(six.string_types))
self._assert_type("label", [type(None), str])
verify_label(self.label)

def _validate_final(self):
Expand Down Expand Up @@ -397,7 +391,7 @@ class BaseProduct(productmd.common.MetadataBase):
"""

def __init__(self, metadata):
super(BaseProduct, self).__init__()
super().__init__()
self._section = "base_product"
self._metadata = metadata
self.name = None #: (*str*) -- Product name, for example: "Fedora", "Red Hat Enterprise Linux"
Expand All @@ -421,20 +415,20 @@ def __str__(self):
return "%s-%s" % (self.short, self.version)

def _validate_name(self):
self._assert_type("name", list(six.string_types))
self._assert_type("name", [str])

def _validate_version(self):
"""If the version starts with a digit, it must be a sematic-versioning
style string.
"""
self._assert_type("version", list(six.string_types))
self._assert_type("version", [str])
self._assert_matches_re("version", [RELEASE_VERSION_RE])

def _validate_short(self):
self._assert_type("short", list(six.string_types))
self._assert_type("short", [str])

def _validate_type(self):
self._assert_type("type", list(six.string_types))
self._assert_type("type", [str])
self._assert_value("type", productmd.common.RELEASE_TYPES)

@property
Expand Down Expand Up @@ -478,7 +472,7 @@ class Release(BaseProduct):
"""

def __init__(self, metadata):
super(Release, self).__init__(metadata)
super().__init__(metadata)
self._section = "release"

self.name = None #: (*str*) -- Release name, for example: "Fedora", "Red Hat Enterprise Linux"
Expand All @@ -494,7 +488,7 @@ def __cmp__(self, other):
return BaseProduct.__cmp__(self, other)

def _validate_type(self):
self._assert_type("type", list(six.string_types))
self._assert_type("type", [str])
self._assert_value("type", productmd.common.RELEASE_TYPES)

def _validate_is_layered(self):
Expand Down Expand Up @@ -539,7 +533,7 @@ def deserialize_1_0(self, data):

class VariantBase(productmd.common.MetadataBase):
def __init__(self, metadata):
super(VariantBase, self).__init__()
super().__init__()
self._metadata = metadata
self.parent = None
self.variants = {}
Expand All @@ -548,7 +542,7 @@ def __repr__(self):
if hasattr(self, "compose"):
return u'<%s:%s>' % (self.__class__.__name__, self._metadata.compose.id)
else:
return super(VariantBase, self).__repr__()
return super().__repr__()

def __getitem__(self, name):
# There can be exceptions, like $variant-optional on top-level,
Expand Down Expand Up @@ -625,7 +619,7 @@ def get_variants(self, arch=None, types=None, recursive=False):
if "self" in types:
result.append(self)

for variant in six.itervalues(self.variants):
for variant in self.variants.values():
if types and variant.type not in types:
continue
if arch and arch not in variant.arches.union(["src"]):
Expand All @@ -642,8 +636,9 @@ class Variants(VariantBase):
"""
This class is a container for compose variants.
"""

def __init__(self, metadata):
super(Variants, self).__init__(metadata)
super().__init__(metadata)
self._section = "variants"

def serialize(self, data):
Expand Down Expand Up @@ -813,7 +808,7 @@ def __repr__(self):
return u'<%s:%s>' % (self.__class__.__name__, self.uid)

def _validate_id(self):
self._assert_type("id", list(six.string_types))
self._assert_type("id", [str])
self._assert_matches_re("id", [r"^[a-zA-Z0-9]+$"])

def _validate_uid(self):
Expand All @@ -828,7 +823,7 @@ def _validate_uid(self):
raise ValueError("UID '%s' doesn't align with parent UID '%s'" % (self.uid, uid))

def _validate_name(self):
self._assert_type("name", list(six.string_types))
self._assert_type("name", [str])
self._assert_not_blank("name")

def _validate_type(self):
Expand Down
2 changes: 1 addition & 1 deletion productmd/discinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class DiscInfo(productmd.common.MetadataBase):
"""

def __init__(self):
super(DiscInfo, self).__init__()
super().__init__()
self.timestamp = None #: Timestamp in float format
self.description = None #: Release description, for example: Fedora 20
self.arch = None #: Media architecture, for example: x86_64
Expand Down
4 changes: 1 addition & 3 deletions productmd/extra_files.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-

# Copyright (C) 2019 Red Hat, Inc.
#
# This library is free software; you can redistribute it and/or
Expand Down Expand Up @@ -28,7 +26,7 @@

class ExtraFiles(productmd.common.MetadataBase):
def __init__(self):
super(ExtraFiles, self).__init__()
super().__init__()
self.header = Header(self, "productmd.extra_files")
self.compose = Compose(self)
self.extra_files = {}
Expand Down
Loading

0 comments on commit 84a559d

Please sign in to comment.