Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Patch stash to run with Pythonista 3.4 beta #463

Merged
merged 14 commits into from
Mar 15, 2023
Merged
Show file tree
Hide file tree
Changes from 11 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/check-code-and-run-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Check code and run tests

on: [push]

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["2.7", "3.6", "3.8"]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip wheel setuptools
pip install ".[testing]"
- name: Analysing the code with flake8
run: |
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=88 --statistics
- name: Running tests
run: |
py.test --version
Copy link
Collaborator

@cclauss cclauss Mar 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is deprecated to run pytest with the dot.

Suggested change
py.test --version
pytest --version

# make install test work...
export PYTHONPATH=$(python -m site --user-site)
pytest tests/ --ignore=tests/system/data/ --showlocals --verbose --show-capture=all --log-level=debug
6 changes: 5 additions & 1 deletion bin/wget.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@

import sys
import argparse
import ssl

from six.moves.urllib.request import urlopen

import certifi

try:
import console
except ImportError:
Expand Down Expand Up @@ -51,7 +54,8 @@ def main(args):
try:

print('Opening: %s\n' % url)
u = urlopen(url)
context = ssl.create_default_context(cafile=certifi.where())
u = urlopen(url, context=context)

meta = u.info()
try:
Expand Down
45 changes: 29 additions & 16 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,35 @@

# =================== SETUP ===================

from distutils.core import setup
from setuptools import find_packages
from setuptools import setup,find_packages


TEST_REQUIREMENTS = [
"pyparsing==2.0.1",
"pytest>=3.6.0",
"flake8>=3.5.0",
"pycrypto==2.6",
"requests==2.9.1",
]
if sys.version_info.major==2:
INSTALL_REQUIREMENTS = [
"rsa==4.5",
"six", # required by StaSh
"pyperclip", # required by libdist for copy/paste on PC
"requests==2.9.1",
"pycrypto==2.6",
"pyte==0.8.1",
]
TEST_REQUIREMENTS = [
"pyparsing==2.0.2",
"pytest==4.6.11",
"flake8>=3.7.9",
]
else:
INSTALL_REQUIREMENTS=[
"six", # required by StaSh
"pyperclip", # required by libdist for copy/paste on PC
"requests",
"pycrypto",
"pyte",
],
TEST_REQUIREMENTS = [
"pyparsing",
"pytest",
"flake8>=3.7.9",
]


PARENT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
Expand Down Expand Up @@ -125,12 +143,7 @@ def get_stash_version(corepath):
},
scripts=[os.path.join(STASH_DIR, "launch_stash.py")],
zip_safe=False,
install_requires=[
"six", # required by StaSh
"pyperclip", # required by libdist for copy/paste on PC
"requests",
"pyte",
],
install_requires=INSTALL_REQUIREMENTS,
extras_require={
"testing": TEST_REQUIREMENTS,
},
Expand Down
10 changes: 9 additions & 1 deletion system/shcommon.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,15 @@
if IN_PYTHONISTA:
import plistlib

_properties = plistlib.readPlist(os.path.join(os.path.dirname(sys.executable), 'Info.plist'))
info_plist_path = os.path.join(os.path.dirname(sys.executable), 'Info.plist')
if hasattr(plistlib, 'readPlist'):
_properties = plistlib.readPlist(info_plist_path)
elif hasattr(plistlib, 'load'):
with open(info_plist_path, 'rb') as info_plist:
_properties = plistlib.load(info_plist)
else:
raise Exception('`plistlib` does not support reading a plist file.')

PYTHONISTA_VERSION = _properties['CFBundleShortVersionString']
PYTHONISTA_VERSION_LONG = _properties['CFBundleVersion']

Expand Down
11 changes: 9 additions & 2 deletions system/shthreads.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,9 +261,16 @@ def status(self):
# False | not None | stopped
# True | None | impossible
# True | not None | running
if self.isAlive():

# `Thread.isAlive()` was removed in Python 3.9
if hasattr(self, 'is_alive'):
is_alive = self.is_alive()
else:
is_alive = self.isAlive()

if is_alive:
Copy link
Collaborator

@cclauss cclauss Mar 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thread.is_alive() was added in Python 2.6 so we can merely change .isAlive() to .is_alive() everywhere. See #478

Suggested change
# `Thread.isAlive()` was removed in Python 3.9
if hasattr(self, 'is_alive'):
is_alive = self.is_alive()
else:
is_alive = self.isAlive()
if is_alive:
if self.is_alive():

return self.STARTED
elif (not self.is_alive()) and (self.ident is not None):
elif (not is_alive) and (self.ident is not None):
return self.STOPPED
else:
return self.CREATED
Expand Down
21 changes: 16 additions & 5 deletions system/shui/pythonista_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,14 +385,14 @@ def _vk_tapped(self, sender):
# noinspection PyAttributeOutsideInit,PyUnusedLocal,PyPep8Naming
class ShTerminal(ShBaseTerminal):
"""
This is a wrapper class of the actual TextView that subclass the SUITextView.
This is a wrapper class of the actual TextView that subclass the SUITextView/SUITextView_PY3.
The wrapper is used to encapsulate the objc calls so that it behaves more like
a regular ui.TextView.
"""

def __init__(self, stash, parent, superview, width, height):

# Create the actual TextView by subclass SUITextView
# Create the actual TextView by subclass SUITextView/SUITextView_PY3
UIKeyCommand = ObjCClass('UIKeyCommand')

def kcDispatcher_(_self, _cmd, _sender):
Expand Down Expand Up @@ -490,7 +490,10 @@ def keyCommands(_self, _cmd):
('UIKeyInputRightArrow', 0): parent.arrowRightAction,
}

_ShTerminal = create_objc_class('_ShTerminal', ObjCClass('SUITextView'), [keyCommands, kcDispatcher_])
try:
_ShTerminal = create_objc_class('_ShTerminal', ObjCClass('SUITextView'), [keyCommands, kcDispatcher_])
except ValueError:
_ShTerminal = create_objc_class('_ShTerminal', ObjCClass('SUITextView_PY3'), [keyCommands, kcDispatcher_])

self.is_editing = False

Expand Down Expand Up @@ -883,7 +886,7 @@ def _build_attributed_string(self, chars):

def render(self, no_wait=False):
"""
Render the screen buffer to the UITextView. Normally the rendering process
Render the screen buffer to the SUITextView/SUITextView_PY3. Normally the rendering process
is delayed to throttle the total attempts of rendering.
:param bool no_wait: Immediately render the screen without delay.
"""
Expand All @@ -894,7 +897,15 @@ def render(self, no_wait=False):
self.render_thread.cancel()
self._render()
else: # delayed rendering
if self.render_thread is None or not self.render_thread.isAlive():
# `Thread.isAlive()` was removed in Python 3.9
is_render_thread_alive = None
if self.render_thread is not None:
if hasattr(self.render_thread, 'is_alive'):
is_render_thread_alive = self.render_thread.is_alive()
else:
is_render_thread_alive = self.render_thread.isAlive()

if self.render_thread is None or not is_render_thread_alive:
Copy link
Collaborator

@cclauss cclauss Mar 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thread.is_alive() was added in Python 2.6 so we can merely change .isAlive() to .is_alive() everywhere. See #478

Suggested change
# `Thread.isAlive()` was removed in Python 3.9
is_render_thread_alive = None
if self.render_thread is not None:
if hasattr(self.render_thread, 'is_alive'):
is_render_thread_alive = self.render_thread.is_alive()
else:
is_render_thread_alive = self.render_thread.isAlive()
if self.render_thread is None or not is_render_thread_alive:
if self.render_thread is None or not self.render_thread.is_alive():

self.render_thread = sh_delay(self._render, self.RENDER_INTERVAL)
# Do nothing if there is already a delayed rendering thread waiting

Expand Down
4 changes: 2 additions & 2 deletions tests/pip/test_pip.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ def test_install_pypi_nobinary(self):
@requires_network
def test_install_pypi_onlybinary(self):
"""test 'pip install --only-binary :all: <pypi_package>'."""
output = self.run_command("pip --verbose install --only-binary :all: rsa", exitcode=0)
output = self.run_command("pip --verbose install --only-binary :all: rsa==4.5", exitcode=0)
self.assertIn("Downloading package", output)
self.assert_did_run_setup(output, allow_source=False)
self.assertIn("Package installed: rsa", output)
Expand All @@ -153,7 +153,7 @@ def test_install_command(self):
self.run_command("pyrsa-keygen --help", exitcode=127)

# 2. install
output = self.run_command("pip --verbose install rsa", exitcode=0)
output = self.run_command("pip --verbose install rsa==4.5", exitcode=0)
self.assertIn("Downloading package", output)
self.assert_did_run_setup(output)
self.assertIn("Package installed: rsa", output)
Expand Down