Skip to content

Commit a60c57a

Browse files
committed
Initial support for Python 3.5+ // Resolve platformio#895 Resolve platformio#1365
1 parent fabaade commit a60c57a

35 files changed

+265
-198
lines changed

.appveyor.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ platform:
77
environment:
88
matrix:
99
- TOXENV: "py27"
10+
- TOXENV: "py35"
11+
- TOXENV: "py36"
1012

1113
install:
1214
- cmd: git submodule update --init --recursive

.pylintrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@ confidence=
2020
# --disable=W"
2121
# disable=import-star-module-level,old-octal-literal,oct-method,print-statement,unpacking-in-except,parameter-unpacking,backtick,old-raise-syntax,old-ne-operator,long-suffix,dict-view-method,dict-iter-method,metaclass-assignment,next-method-called,raising-string,indexing-exception,raw_input-builtin,long-builtin,file-builtin,execfile-builtin,coerce-builtin,cmp-builtin,buffer-builtin,basestring-builtin,apply-builtin,filter-builtin-not-iterating,using-cmp-argument,useless-suppression,range-builtin-not-iterating,suppressed-message,no-absolute-import,old-division,cmp-method,reload-builtin,zip-builtin-not-iterating,intern-builtin,unichr-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,input-builtin,round-builtin,hex-method,nonzero-method,map-builtin-not-iterating
2222

23-
disable=locally-disabled,missing-docstring,invalid-name,too-few-public-methods,redefined-variable-type,import-error,similarities,unsupported-membership-test,unsubscriptable-object,ungrouped-imports,cyclic-import,superfluous-parens
23+
disable=locally-disabled,missing-docstring,invalid-name,too-few-public-methods,redefined-variable-type,import-error,similarities,unsupported-membership-test,unsubscriptable-object,ungrouped-imports,cyclic-import,superfluous-parens,useless-object-inheritance,useless-import-alias

.travis.yml

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,18 @@ matrix:
66
sudo: false
77
python: 2.7
88
env: TOX_ENV=docs
9-
- os: linux
10-
sudo: false
11-
python: 2.7
12-
env: TOX_ENV=lint
139
- os: linux
1410
sudo: required
1511
python: 2.7
1612
env: TOX_ENV=py27
13+
- os: linux
14+
sudo: required
15+
python: 3.5
16+
env: TOX_ENV=py35
17+
- os: linux
18+
sudo: required
19+
python: 3.6
20+
env: TOX_ENV=py36
1721
- os: osx
1822
language: generic
1923
env: TOX_ENV=skipexamples
@@ -24,7 +28,7 @@ install:
2428
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then sudo pip install "tox==3.0.0"; else pip install -U tox; fi
2529

2630
# ChipKIT issue: install 32-bit support for GCC PIC32
27-
- if [[ "$TOX_ENV" == "py27" ]] && [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install libc6-i386; fi
31+
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install libc6-i386; fi
2832

2933
script:
3034
- tox -e $TOX_ENV

HISTORY.rst

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
11
Release Notes
22
=============
33

4+
PlatformIO 4.0
5+
--------------
6+
7+
4.0.0 (2019-??-??)
8+
~~~~~~~~~~~~~~~~~~
9+
10+
* Added Python 3.5+ support
11+
(`issue #895 <https://github.com/platformio/platformio-core/issues/895>`_)
12+
413
PlatformIO 3.0
514
--------------
615

7-
3.6.4 (2018-??-??)
16+
3.6.4 (2019-??-??)
817
~~~~~~~~~~~~~~~~~~
918

1019
* Improved Project Generator for IDEs:

platformio/__init__.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
import sys
16-
17-
VERSION = (3, 6, "4b1")
15+
VERSION = (4, 0, "0a1")
1816
__version__ = ".".join([str(s) for s in VERSION])
1917

2018
__title__ = "platformio"
@@ -33,10 +31,3 @@
3331
__copyright__ = "Copyright 2014-present PlatformIO"
3432

3533
__apiurl__ = "https://api.platformio.org"
36-
37-
if sys.version_info < (2, 7, 0) or sys.version_info >= (3, 0, 0):
38-
msg = ("PlatformIO Core v%s does not run under Python version %s.\n"
39-
"Minimum supported version is 2.7, please upgrade Python.\n"
40-
"Python 3 is not yet supported.\n")
41-
sys.stderr.write(msg % (__version__, sys.version))
42-
sys.exit(1)

platformio/__main__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def _handle_obsolate_command(name):
5353
if name == "platforms":
5454
from platformio.commands import platform
5555
return platform.cli
56-
elif name == "serialports":
56+
if name == "serialports":
5757
from platformio.commands import device
5858
return device.cli
5959
raise AttributeError()

platformio/app.py

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,11 @@ def get_cache_path(self, key):
169169
@staticmethod
170170
def key_from_args(*args):
171171
h = hashlib.md5()
172-
for data in args:
173-
h.update(str(data))
172+
for arg in args:
173+
if not arg:
174+
continue
175+
arg = str(arg)
176+
h.update(arg if util.PY2 else arg.encode())
174177
return h.hexdigest()
175178

176179
def get(self, key):
@@ -191,7 +194,7 @@ def set(self, key, data, valid):
191194
if not isdir(self.cache_dir):
192195
os.makedirs(self.cache_dir)
193196
tdmap = {"s": 1, "m": 60, "h": 3600, "d": 86400}
194-
assert valid.endswith(tuple(tdmap.keys()))
197+
assert valid.endswith(tuple(tdmap))
195198
expire_time = int(time() + tdmap[valid[-1]] * int(valid[:-1]))
196199

197200
if not self._lock_dbindex():
@@ -339,21 +342,22 @@ def is_disabled_progressbar():
339342

340343
def get_cid():
341344
cid = get_state_item("cid")
342-
if not cid:
343-
_uid = None
344-
if getenv("C9_UID"):
345-
_uid = getenv("C9_UID")
346-
elif getenv("CHE_API", getenv("CHE_API_ENDPOINT")):
347-
try:
348-
_uid = requests.get("{api}/user?token={token}".format(
349-
api=getenv("CHE_API", getenv("CHE_API_ENDPOINT")),
350-
token=getenv("USER_TOKEN"))).json().get("id")
351-
except: # pylint: disable=bare-except
352-
pass
353-
cid = str(
354-
uuid.UUID(
355-
bytes=hashlib.md5(str(_uid if _uid else uuid.getnode())).
356-
digest()))
357-
if "windows" in util.get_systype() or os.getuid() > 0:
358-
set_state_item("cid", cid)
345+
if cid:
346+
return cid
347+
uid = None
348+
if getenv("C9_UID"):
349+
uid = getenv("C9_UID")
350+
elif getenv("CHE_API", getenv("CHE_API_ENDPOINT")):
351+
try:
352+
uid = requests.get("{api}/user?token={token}".format(
353+
api=getenv("CHE_API", getenv("CHE_API_ENDPOINT")),
354+
token=getenv("USER_TOKEN"))).json().get("id")
355+
except: # pylint: disable=bare-except
356+
pass
357+
if not uid:
358+
uid = uuid.getnode()
359+
cid = uuid.UUID(bytes=hashlib.md5(str(uid).encode()).digest())
360+
cid = str(cid)
361+
if "windows" in util.get_systype() or os.getuid() > 0:
362+
set_state_item("cid", cid)
359363
return cid

platformio/builder/main.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@
9292
variables=commonvars,
9393

9494
# Propagating External Environment
95-
PIOVARIABLES=commonvars.keys(),
95+
PIOVARIABLES=list(commonvars.keys()),
9696
ENV=environ,
9797
UNIX_TIME=int(time()),
9898
PIOHOME_DIR=util.get_home_dir(),
@@ -125,9 +125,11 @@
125125
env = DefaultEnvironment(**DEFAULT_ENV_OPTIONS)
126126

127127
# decode common variables
128-
for k in commonvars.keys():
128+
for k in list(commonvars.keys()):
129129
if k in env:
130130
env[k] = base64.b64decode(env[k])
131+
if isinstance(env[k], bytes):
132+
env[k] = env[k].decode()
131133
if k in MULTILINE_VARS:
132134
env[k] = util.parse_conf_multi_values(env[k])
133135

@@ -161,7 +163,9 @@
161163
env.LoadPioPlatform(commonvars)
162164

163165
env.SConscriptChdir(0)
164-
env.SConsignFile(join("$PROJECTBUILD_DIR", ".sconsign.dblite"))
166+
env.SConsignFile(
167+
join("$PROJECTBUILD_DIR",
168+
".sconsign.dblite" if util.PY2 else ".sconsign3.dblite"))
165169

166170
for item in env.GetExtraScripts("pre"):
167171
env.SConscript(item, exports="env")

platformio/builder/tools/piolib.py

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,19 @@ def get_used_frameworks(env, path):
7474
if not env.IsFileWithExt(
7575
fname, piotool.SRC_BUILD_EXT + piotool.SRC_HEADER_EXT):
7676
continue
77-
with open(join(root, fname)) as f:
78-
content = f.read()
79-
if "Arduino.h" in content and include_re.search(content):
80-
return ["arduino"]
81-
elif "mbed.h" in content and include_re.search(content):
82-
return ["mbed"]
77+
content = ""
78+
try:
79+
with open(join(root, fname)) as f:
80+
content = f.read()
81+
except UnicodeDecodeError:
82+
with open(join(root, fname), encoding="latin-1") as f:
83+
content = f.read()
84+
if not content:
85+
continue
86+
if "Arduino.h" in content and include_re.search(content):
87+
return ["arduino"]
88+
if "mbed.h" in content and include_re.search(content):
89+
return ["mbed"]
8390
return []
8491

8592

@@ -183,9 +190,9 @@ def get_include_dirs(self):
183190

184191
@property
185192
def build_dir(self):
186-
return join("$BUILD_DIR",
187-
"lib%s" % hashlib.sha1(self.path).hexdigest()[:3],
188-
basename(self.path))
193+
lib_hash = hashlib.sha1(self.path if util.PY2 else self.path.
194+
encode()).hexdigest()[:3]
195+
return join("$BUILD_DIR", "lib%s" % lib_hash, basename(self.path))
189196

190197
@property
191198
def build_flags(self):
@@ -227,7 +234,7 @@ def is_built(self):
227234

228235
@staticmethod
229236
def validate_ldf_mode(mode):
230-
if isinstance(mode, basestring):
237+
if isinstance(mode, util.string_types):
231238
mode = mode.strip().lower()
232239
if mode in LibBuilderBase.LDF_MODES:
233240
return mode
@@ -239,7 +246,7 @@ def validate_ldf_mode(mode):
239246

240247
@staticmethod
241248
def validate_compat_mode(mode):
242-
if isinstance(mode, basestring):
249+
if isinstance(mode, util.string_types):
243250
mode = mode.strip().lower()
244251
if mode in LibBuilderBase.COMPAT_MODES:
245252
return mode
@@ -612,9 +619,9 @@ def _is_arduino_manifest(self):
612619
def src_filter(self):
613620
if "srcFilter" in self._manifest.get("build", {}):
614621
return self._manifest.get("build").get("srcFilter")
615-
elif self.env['SRC_FILTER']:
622+
if self.env['SRC_FILTER']:
616623
return self.env['SRC_FILTER']
617-
elif self._is_arduino_manifest():
624+
if self._is_arduino_manifest():
618625
return ArduinoLibBuilder.src_filter.fget(self)
619626
return LibBuilderBase.src_filter.fget(self)
620627

platformio/builder/tools/piomisc.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ def append_prototypes(self, contents):
162162
if not prototypes:
163163
return contents
164164

165-
prototype_names = set([m.group(3).strip() for m in prototypes])
165+
prototype_names = set(m.group(3).strip() for m in prototypes)
166166
split_pos = prototypes[0].start()
167167
match_ptrs = re.search(
168168
self.PROTOPTRS_TPLRE % ("|".join(prototype_names)),
@@ -212,7 +212,7 @@ def _get_compiler_type(env):
212212
output = "".join([result['out'], result['err']]).lower()
213213
if "clang" in output and "LLVM" in output:
214214
return "clang"
215-
elif "gcc" in output:
215+
if "gcc" in output:
216216
return "gcc"
217217
return None
218218

0 commit comments

Comments
 (0)