Skip to content
This repository has been archived by the owner on Jul 19, 2022. It is now read-only.

Support Python 3 #51

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/pythonpackage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Python package

on: [push]

jobs:
build:

runs-on: ${{ matrix.os }}
strategy:
max-parallel: 4
matrix:
python-version: [2.7, 3.5, 3.6, 3.7, 3.8]
os: [ubuntu-latest, macos-latest]

steps:
- uses: actions/checkout@v1
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
with:
python-version: ${{ matrix.python-version }}
- name: Lint with flake8
run: |
pip install flake8
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Test with Nose
run: |
pip install tox tox-gh-actions
tox
11 changes: 6 additions & 5 deletions example.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,14 @@

#To create an item
item = {
"fields":[
{"external_id":"org-name", "values":[{"value":"The Items API sucks"}]}
]
"fields":[
{"external_id":"org-name", "values":[{"value":"The Items API sucks"}]}
]
}
#print c.Application.find(179652)

app_id = c.Application.find(179652)
c.Item.create(app_id, item)

#Undefined and created at runtime example
#print c.transport.GET.user.status()

Expand Down
1 change: 1 addition & 0 deletions pypodio2/adapters.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from __future__ import print_function

import json

Expand Down
10 changes: 9 additions & 1 deletion pypodio2/areas.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
# -*- coding: utf-8 -*-
from future import standard_library
standard_library.install_aliases()
from builtins import str
from builtins import object
import json

try:
from urllib.parse import urlencode
except ImportError:
from urllib import urlencode
from urllib.parse import urlencode


class ApiErrorException(Exception):
pass


class Area(object):
Expand Down
1 change: 1 addition & 0 deletions pypodio2/client.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-

from builtins import object
from . import areas


Expand Down
30 changes: 18 additions & 12 deletions pypodio2/encode.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,16 @@

multipart/form-data is the standard way to upload files over HTTP"""

from past.builtins import cmp
from future import standard_library
standard_library.install_aliases()
from builtins import next
from builtins import str
from builtins import object
import mimetypes
import os
import re
import urllib
import urllib.request, urllib.parse, urllib.error
from email.header import Header

__all__ = ['gen_boundary', 'encode_and_quote', 'MultipartParam',
Expand Down Expand Up @@ -44,17 +50,17 @@ def encode_and_quote(data):
if data is None:
return None

if isinstance(data, unicode):
if isinstance(data, str):
data = data.encode("utf-8")
return urllib.quote_plus(data)
return urllib.parse.quote_plus(data)


def _strify(s):
"""If s is a unicode string, encode it to UTF-8 and return the results,
otherwise return str(s), or None if s is None"""
if s is None:
return None
if isinstance(s, unicode):
if isinstance(s, str):
return s.encode("utf-8")
return str(s)

Expand Down Expand Up @@ -99,7 +105,7 @@ def __init__(self, name, value=None, filename=None, filetype=None,
if filename is None:
self.filename = None
else:
if isinstance(filename, unicode):
if isinstance(filename, str):
# Encode with XML entities
self.filename = filename.encode("ascii", "xmlcharrefreplace")
else:
Expand Down Expand Up @@ -166,7 +172,7 @@ def from_params(cls, params):
MultipartParam object names must match the given names in the
name,value pairs or mapping, if applicable."""
if hasattr(params, 'items'):
params = params.items()
params = list(params.items())

retval = []
for item in params:
Expand Down Expand Up @@ -323,13 +329,13 @@ def get_headers(params, boundary):
"""Returns a dictionary with Content-Type and Content-Length headers
for the multipart/form-data encoding of ``params``."""
headers = {}
boundary = urllib.quote_plus(boundary)
boundary = urllib.parse.quote_plus(boundary)
headers['Content-Type'] = "multipart/form-data; boundary=%s" % boundary
headers['Content-Length'] = str(get_body_size(params, boundary))
return headers


class MultipartYielder:
class MultipartYielder(object):
def __init__(self, params, boundary, cb):
self.params = params
self.boundary = boundary
Expand All @@ -344,12 +350,12 @@ def __init__(self, params, boundary, cb):
def __iter__(self):
return self

def next(self):
def __next__(self):
"""generator function to yield multipart/form-data representation
of parameters"""
if self.param_iter is not None:
try:
block = self.param_iter.next()
block = next(self.param_iter)
self.current += len(block)
if self.cb:
self.cb(self.p, self.current, self.total)
Expand All @@ -373,7 +379,7 @@ def next(self):
self.p = self.params[self.i]
self.param_iter = self.p.iter_encode(self.boundary)
self.i += 1
return self.next()
return next(self)

def reset(self):
self.i = 0
Expand Down Expand Up @@ -425,7 +431,7 @@ def multipart_encode(params, boundary=None, cb=None):
if boundary is None:
boundary = gen_boundary()
else:
boundary = urllib.quote_plus(boundary)
boundary = urllib.parse.quote_plus(boundary)

headers = get_headers(params, boundary)
params = MultipartParam.from_params(params)
Expand Down
6 changes: 5 additions & 1 deletion pypodio2/transport.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# -*- coding: utf-8 -*-
from future import standard_library
standard_library.install_aliases()
from builtins import str
from builtins import object
from httplib2 import Http

try:
from urllib.parse import urlencode
except ImportError:
from urllib import urlencode
from urllib.parse import urlencode

from .encode import multipart_encode

Expand Down
17 changes: 14 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
from setuptools import setup

extras = {
'test': [
'mock',
'nose',
'tox',
]
}

setup(
name="pypodio2",
version="0.2",
version="1.0.0b0",
description="Python wrapper for the Podio API",
author="Podio",
author_email="mail@podio.com",
url="https://github.com/podio/podio-py",
license="MIT",
packages=["pypodio2"],
install_requires=["httplib2"],
tests_require=["nose", "mock", "tox"],
install_requires=[
"httplib2",
"future",
],
extras_require=extras,
test_suite="nose.collector",
classifiers=[
"Development Status :: 4 - Beta",
Expand Down
17 changes: 11 additions & 6 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
[tox]
envlist = py27,py35
envlist = py27,py35,py36,py37,py38

[gh-actions]
python =
2.7: py27
3.5: py35
3.6: py36
3.7: py37
3.8: py38

[testenv]
commands = {envpython} setup.py nosetests
deps =
nose
mock
httplib2
extras = test
commands = {posargs:nosetests}