Skip to content

Commit

Permalink
Drop legacy python (#25)
Browse files Browse the repository at this point in the history
* Bumped version for breaking release.

* Drop support for Python 2.7, 3.5, 3.6.

* Fix conversion of bytes. (It was already wrong before as six.u(var) is a no-op in Python 3.)

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
Michael Howitz and pre-commit-ci[bot] authored Aug 23, 2023
1 parent e52c003 commit 069c69b
Show file tree
Hide file tree
Showing 14 changed files with 125 additions and 177 deletions.
16 changes: 7 additions & 9 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,27 @@ jobs:
matrix:
config:
# [Python version, tox env]
- ["2.7", "py27"]
- ["3.7", "py37"]
- ["3.8", "py38"]
- ["3.9", "py39"]
- ["3.10", "py310"]
- ["3.11", "py311"]
- ["pypy2", "pypy"]
- ["pypy3", "pypy3"]
- ["3.8", "coverage"]
runs-on: ubuntu-20.04
- ["pypy-3.9", "pypy3"]
- ["3.11", "coverage"]
runs-on: ubuntu-latest
name: ${{ matrix.config[1] }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Decrypt config
run: ./.github/scripts/decrypt_collmex_ini.sh
env:
GPG_PASSWORD_COLLMEX_INI: ${{ secrets.GPG_PASSWORD_COLLMEX_INI }}
- name: Set up Python
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.config[0] }}
- name: Pip cache
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('setup.*', 'tox.ini') }}
Expand All @@ -56,7 +54,7 @@ jobs:
- name: Coverage
if: matrix.config[1] == 'coverage'
run: |
pip install coveralls coverage-python-version
pip install coveralls
coveralls --service=github
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
10 changes: 4 additions & 6 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
Changes
=======

1.10 (unreleased)
-----------------
2.0 (unreleased)
----------------

- Drop support for Python 3.5 and 3.6.
- Drop support for Python 2.7, 3.5, 3.6.

- Add support for Python 3.9, 3.10, 3.11.

- Avoid password exhaustion by using invalid username for tests.

- Enable the tests to use fewer connections.

- Switch to GHA as CI system.
- Fix the tests to use fewer connections.


1.9 (2019-09-02)
Expand Down
6 changes: 2 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setup(
name='gocept.collmex',
version='1.10.dev0',
version='2.0.dev0',
author='gocept',
author_email='mail@gocept.com',
description='Python-bindings for the Collmex import/export API',
Expand All @@ -17,8 +17,6 @@
'License :: OSI Approved',
'License :: OSI Approved :: Zope Public License',
'Operating System :: OS Independent',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
Expand All @@ -40,6 +38,7 @@
zip_safe=False,
license='ZPL 2.1',
namespace_packages=['gocept'],
python_requires='>=3.7',
install_requires=[
'gocept.cache >= 0.6.1',
'setuptools >= 1.0',
Expand All @@ -48,7 +47,6 @@
'zope.interface >= 4.0',
'webtest >= 2.0',
'wsgiproxy2',
'six >= 1.7.0'
],
extras_require=dict(
test=[
Expand Down
66 changes: 20 additions & 46 deletions src/gocept/collmex/collmex.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,17 @@
from __future__ import unicode_literals
from zope.interface import implementer
import csv
import gocept.cache.method
import gocept.cache.property
import gocept.collmex.interfaces
import gocept.collmex.model
import gocept.collmex.utils
import io
import logging
import re
import six
import threading
import transaction
import transaction.interfaces


try:
import urllib.request as urllib2
except ImportError:
import urllib2

from zope.interface import implementer
import urllib.request
import webtest
import zope.deprecation
import zope.interface
Expand All @@ -29,14 +22,9 @@

class CollmexDialect(csv.Dialect):
quoting = csv.QUOTE_ALL
if six.PY3:
delimiter = ';'
quotechar = '"'
lineterminator = '\r\n'
else:
delimiter = b';'
quotechar = b'"'
lineterminator = b'\r\n'
delimiter = ';'
quotechar = '"'
lineterminator = '\r\n'
doublequote = True
skipinitialspace = True

Expand All @@ -46,14 +34,14 @@ class APIError(Exception):


@implementer(transaction.interfaces.IDataManager)
class CollmexDataManager(object):
class CollmexDataManager:

def __init__(self, utility):
self.utility = utility
self._reset()

def _reset(self):
self.data = six.StringIO()
self.data = io.StringIO()
self._joined = False
self._transaction = None
self.voted = False
Expand Down Expand Up @@ -104,7 +92,7 @@ def sortKey(self):


@implementer(gocept.collmex.interfaces.ICollmex)
class Collmex(object):
class Collmex:

# XXX should go on CollmexDialect but the csv module's magic prevents it
NULL = gocept.collmex.interfaces.NULL
Expand All @@ -121,7 +109,7 @@ def __init__(self, customer_id=None, company_id=None,
try:
# try to use credentials from ini file 'collmex.ini'
cred = gocept.collmex.utils.get_collmex_credentials()
except IOError as error:
except OSError as error:
if invalid_credentials:
raise ValueError(
'Not enough credentials given for initialization and no '
Expand Down Expand Up @@ -161,12 +149,10 @@ def connection(self):
return self._local.connection

def create(self, item):
data = six.StringIO()
data = io.StringIO()
writer = csv.writer(data, dialect=CollmexDialect)
item.company = self.company_id
writer.writerow([elem.encode('UTF-8')
if isinstance(elem, six.text_type) and six.PY2
else elem for elem in list(item)])
writer.writerow([elem for elem in list(item)])
self.connection.register_data(data.getvalue())

def create_invoice(self, items):
Expand Down Expand Up @@ -303,12 +289,9 @@ def invalidate(self, dummy):

@gocept.cache.method.memoize_on_attribute('_cache', timeout=5 * 60)
def _query_objects(self, function, *args):
data = six.StringIO()
data = io.StringIO()
writer = csv.writer(data, dialect=CollmexDialect)
writer.writerow([elem.encode('UTF-8')
if isinstance(elem, six.text_type) and six.PY2
else elem
for elem in (function,) + args])
writer.writerow([elem for elem in (function,) + args])
lines = self._post(data.getvalue())
result = []
for line in lines:
Expand All @@ -321,9 +304,9 @@ def _query_objects(self, function, *args):

def _post(self, data):
data = (data.decode('UTF-8')
if isinstance(data, six.binary_type)
if isinstance(data, bytes)
else data)
data = 'LOGIN;%s;%s\n' % (self.username, self.password) + data
data = 'LOGIN;{};{}\n'.format(self.username, self.password) + data
log.debug(data.replace(self.password, '<PASSWORD>'))
content_type, body = gocept.collmex.utils.encode_multipart_formdata(
[], [('fileName', 'api.csv', data)])
Expand All @@ -332,25 +315,16 @@ def _post(self, data):
% self.customer_id)
content_type_label = 'Content-type'

if six.PY2:
url, body, content_type_label, content_type = [
text.encode(self.encoding) for text in
[url, body, content_type_label, content_type]]
else:
body = body.encode(self.encoding)
body = body.encode(self.encoding)

request = urllib2.Request(url, body)
request = urllib.request.Request(url, body)
request.add_header(content_type_label, content_type)
response = urllib2.urlopen(request)
response = urllib.request.urlopen(request)

if six.PY3:
response = six.StringIO(response.read().decode(self.encoding))
response = io.StringIO(response.read().decode(self.encoding))

lines = list(csv.reader(response, dialect=CollmexDialect))

if six.PY2:
lines = [[line.decode(self.encoding) for line in ls]
for ls in lines]
response.close()
result = lines.pop()
assert len(result) >= 4
Expand Down
Loading

0 comments on commit 069c69b

Please sign in to comment.