Python, Jython, CPython, Libraries, Pip, and Python 2.7 vs 3 - A quick primer

I learned something new today! (:

{ The why of the for-else construct. }

1 Like

you spelt Toilet wrong :laughing: Such a garbage product

I use toilet on every server where I have access to ~/.bashrc. It's helpful to have a rainbow-colored (--gay) banner to remind you which server you've connected to

toilet(1)						      General Commands Manual

NAME

       TOIlet - display large colourful characters

SYNOPSIS

       toilet [ -hkostvSW ] [ -d fontdirectory ]
	      [ -f fontfile ] [ -F filter ] [ -w outputwidth ]
	      [ -I infocode ] [ -E format ] [ message ]

DESCRIPTION

       TOIlet prints text using large characters made of smaller characters. It is similar in many ways to FIGlet with additional features such as
       Unicode handling, colour fonts, filters and various export formats.

USAGE

       TOIlet either reads its input from the command line or from the standard input.

OPTIONS

       -f, --font <name>
	      Use the given font instead of the default value. Fonts are .flf or .tlf files stored in the /usr/share/figlet directory.	Fonts  are
	      looked  first in the font directory, then in the current directory. There is also a special built-in font called term that serves as
	      a fallback if no font is available.

       -d, --directory <dir>
	      Specify the directory in which to look for fonts. The default value is set at build time and usually defaults to /usr/share/figlet. 

       -s, -S, -k, -W, -o
	      Select character composition rules.  -S sets smushing (nicely merging glyphs), -k sets kerning (rendering subcharacters as close	to
	      each  other  as  possible),  -W renders characters at their full width and -o sets overlapping (glyphs slightly overlap the previous
	      one).  -s (default behaviour) uses the font's smushing information if any, otherwise forces overlapping,	or  does  nothing  if  the
	      glyph only has one subcharacter.

       -w, --width <width>
	      Set the output width. By default, TOIlet will wrap its output at 80 character columns.

       -t, --termwidth
	      Set the output width to the terminal width.

       -F, --filter <filters>
       -F, --filter list
       --gay, --metal
	      Specify  a  list of filters to be applied to the output.	<filters> is a colon-separated list of filters such as crop:rotate:gay and
	      the special argument list outputs a list of available filters.

	      --gay and --metal are shortcuts to commonly used filters that are guaranteed to exist. Several -F flags can also be specified on the
	      command line, in which case filters will be applied in order of appearance.

       -E, --export <format>
       -E, --export list
       --irc, --html
	      Specify  the  output  format.  By default, TOIlet will output UTF-8 text using ANSI colour codes suitable for most terminals such as
	      XTerm or rxvt.  <format> is the name of the export format as recognised by libcaca. The special argument	list  outputs  a  list	of
	      available export formats.

	      --irc and --html are shortcuts to commonly used export formats that are guaranteed to exist.

       -h, --help
	      Display a short help message and exit.

       -I, --infocode <code>
	      Print a FIGlet infocode. This flag is only here for FIGlet compatibility, see the figlet manpage for more information about it.

       -v, --version
	      Output version information and exit.

EXAMPLES

       toilet Hello World

       toilet Hello | toilet

       tail -f /var/log/messages | toilet -f term --gay

BUGS

       FIGlet compatibility is not complete yet.

AUTHOR

       TOIlet  and this manual page were written by Sam Hocevar <sam@hocevar.net>. There is a webpage available at http://caca.zoy.org/wiki/toilet
       .

SEE ALSO

       figlet(6)

libcaca @PACKAGE_VERSION@					    2006-11-10

Maybe a microservice?

The ability to use pip under Jython 2.7.2 appears to be fundamentally broken by the servers requiring SNI. :frowning:

I’ve got standalone Jython installed and working, but calls to jython -m pip install for any library fail for ERROR: No matching distribution found for requests. Running again with max verbosity will show a snippet like this in the output:

  Getting page https://pypi.org/simple/requests/
  Looking up "https://pypi.org/simple/requests/" in the cache
  Request header has "max_age" as 0, cache bypassed
  Starting new HTTPS connection (1): pypi.org:443
  https://pypi.org:443 "GET /simple/requests/ HTTP/1.1" 403 16
  Status code 403 not in (200, 203, 300, 301)
  Could not fetch URL https://pypi.org/simple/requests/: 403 Client Error: SNI is required for url: https://pypi.org/simple/requests/ - skipping
  ERROR: Could not find a version that satisfies the requirement requests (from versions: none)
Cleaning up...
Removed build tracker '/tmp/pip-req-tracker-va_h9x'
ERROR: No matching distribution found for requests

Some quick searching around implies that Python pre-2.7.9 didn’t support SSL SNI, which implies Jython 2.7.2 probably doesn’t, and it looks like the pypi servers have been moved behind proxies using SNI.

Does anyone know a workaround for this issue?

There is a workaround. As suggested by toml this can be done by:

$ git clone https://github.com/psf/requests.git
Cloning into 'requests'...
remote: Enumerating objects: 24695, done.
remote: Counting objects: 100% (173/173), done.
remote: Compressing objects: 100% (126/126), done.
remote: Total 24695 (delta 97), reused 101 (delta 47), pack-reused 24522
Receiving objects: 100% (24695/24695), 12.38 MiB | 10.81 MiB/s, done.
Resolving deltas: 100% (16197/16197), done.
$ cd requests
$ jython setup.py install
running install
running bdist_egg
running egg_info
creating requests.egg-info
writing dependency_links to requests.egg-info\dependency_links.txt
writing top-level names to requests.egg-info\top_level.txt
writing requests.egg-info\PKG-INFO
writing requirements to requests.egg-info\requires.txt
writing manifest file 'requests.egg-info\SOURCES.txt'
reading manifest file 'requests.egg-info\SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'requests.egg-info\SOURCES.txt'
installing library code to build\bdist.java11.0.11\egg
running install_lib
running build_py
creating build
creating build\lib
creating build\lib\requests
copying requests\adapters.py -> build\lib\requests
copying requests\api.py -> build\lib\requests
copying requests\auth.py -> build\lib\requests
copying requests\certs.py -> build\lib\requests
copying requests\compat.py -> build\lib\requests
copying requests\cookies.py -> build\lib\requests
copying requests\exceptions.py -> build\lib\requests
copying requests\help.py -> build\lib\requests
copying requests\hooks.py -> build\lib\requests
copying requests\models.py -> build\lib\requests
copying requests\packages.py -> build\lib\requests
copying requests\sessions.py -> build\lib\requests
copying requests\status_codes.py -> build\lib\requests
copying requests\structures.py -> build\lib\requests
copying requests\utils.py -> build\lib\requests
copying requests\_internal_utils.py -> build\lib\requests
copying requests\__init__.py -> build\lib\requests
copying requests\__version__.py -> build\lib\requests
creating build\bdist.java11.0.11
creating build\bdist.java11.0.11\egg
creating build\bdist.java11.0.11\egg\requests
copying build\lib\requests\adapters.py -> build\bdist.java11.0.11\egg\requests
copying build\lib\requests\api.py -> build\bdist.java11.0.11\egg\requests
copying build\lib\requests\auth.py -> build\bdist.java11.0.11\egg\requests
copying build\lib\requests\certs.py -> build\bdist.java11.0.11\egg\requests
copying build\lib\requests\compat.py -> build\bdist.java11.0.11\egg\requests
copying build\lib\requests\cookies.py -> build\bdist.java11.0.11\egg\requests
copying build\lib\requests\exceptions.py -> build\bdist.java11.0.11\egg\requests
copying build\lib\requests\help.py -> build\bdist.java11.0.11\egg\requests
copying build\lib\requests\hooks.py -> build\bdist.java11.0.11\egg\requests
copying build\lib\requests\models.py -> build\bdist.java11.0.11\egg\requests
copying build\lib\requests\packages.py -> build\bdist.java11.0.11\egg\requests
copying build\lib\requests\sessions.py -> build\bdist.java11.0.11\egg\requests
copying build\lib\requests\status_codes.py -> build\bdist.java11.0.11\egg\requests
copying build\lib\requests\structures.py -> build\bdist.java11.0.11\egg\requests
copying build\lib\requests\utils.py -> build\bdist.java11.0.11\egg\requests
copying build\lib\requests\_internal_utils.py -> build\bdist.java11.0.11\egg\requests
copying build\lib\requests\__init__.py -> build\bdist.java11.0.11\egg\requests
copying build\lib\requests\__version__.py -> build\bdist.java11.0.11\egg\requests
byte-compiling build\bdist.java11.0.11\egg\requests\adapters.py to adapters$py.class
byte-compiling build\bdist.java11.0.11\egg\requests\api.py to api$py.class
byte-compiling build\bdist.java11.0.11\egg\requests\auth.py to auth$py.class
byte-compiling build\bdist.java11.0.11\egg\requests\certs.py to certs$py.class
byte-compiling build\bdist.java11.0.11\egg\requests\compat.py to compat$py.class
byte-compiling build\bdist.java11.0.11\egg\requests\cookies.py to cookies$py.class
byte-compiling build\bdist.java11.0.11\egg\requests\exceptions.py to exceptions$py.class
byte-compiling build\bdist.java11.0.11\egg\requests\help.py to help$py.class
byte-compiling build\bdist.java11.0.11\egg\requests\hooks.py to hooks$py.class
byte-compiling build\bdist.java11.0.11\egg\requests\models.py to models$py.class
byte-compiling build\bdist.java11.0.11\egg\requests\packages.py to packages$py.class
byte-compiling build\bdist.java11.0.11\egg\requests\sessions.py to sessions$py.class
byte-compiling build\bdist.java11.0.11\egg\requests\status_codes.py to status_codes$py.class
byte-compiling build\bdist.java11.0.11\egg\requests\structures.py to structures$py.class
byte-compiling build\bdist.java11.0.11\egg\requests\utils.py to utils$py.class
byte-compiling build\bdist.java11.0.11\egg\requests\_internal_utils.py to _internal_utils$py.class
byte-compiling build\bdist.java11.0.11\egg\requests\__init__.py to __init__$py.class
byte-compiling build\bdist.java11.0.11\egg\requests\__version__.py to __version__$py.class
creating build\bdist.java11.0.11\egg\EGG-INFO
copying requests.egg-info\PKG-INFO -> build\bdist.java11.0.11\egg\EGG-INFO
copying requests.egg-info\SOURCES.txt -> build\bdist.java11.0.11\egg\EGG-INFO
copying requests.egg-info\dependency_links.txt -> build\bdist.java11.0.11\egg\EGG-INFO
copying requests.egg-info\not-zip-safe -> build\bdist.java11.0.11\egg\EGG-INFO
copying requests.egg-info\requires.txt -> build\bdist.java11.0.11\egg\EGG-INFO
copying requests.egg-info\top_level.txt -> build\bdist.java11.0.11\egg\EGG-INFO
creating dist
creating 'dist\requests-2.26.0-py2.7.egg' and adding 'build\bdist.java11.0.11\egg' to it
removing 'build\bdist.java11.0.11\egg' (and everything under it)
Processing requests-2.26.0-py2.7.egg
creating c:\jython2.7.2\lib\site-packages\requests-2.26.0-py2.7.egg
Extracting requests-2.26.0-py2.7.egg to c:\jython2.7.2\lib\site-packages
Adding requests 2.26.0 to easy-install.pth file

Installed c:\jython2.7.2\lib\site-packages\requests-2.26.0-py2.7.egg
Processing dependencies for requests==2.26.0
Searching for idna<3,>=2.5
Reading https://pypi.org/simple/idna/
Downloading https://files.pythonhosted.org/packages/a2/38/928ddce2273eaa564f6f50de919327bf3a00f091b5baba8dfa9460f3a8a8/idna-2.10-py2.py3-none-any.whl#sha256=b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0
Best match: idna 2.10
Processing idna-2.10-py2.py3-none-any.whl
Installing idna-2.10-py2.py3-none-any.whl to c:\jython2.7.2\lib\site-packages
Adding idna 2.10 to easy-install.pth file

Installed c:\jython2.7.2\lib\site-packages\idna-2.10-py2.7.egg
Searching for chardet<5,>=3.0.2
Reading https://pypi.org/simple/chardet/
Downloading https://files.pythonhosted.org/packages/19/c7/fa589626997dd07bd87d9269342ccb74b1720384a4d739a1872bd84fbe68/chardet-4.0.0-py2.py3-none-any.whl#sha256=f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5
Best match: chardet 4.0.0
Processing chardet-4.0.0-py2.py3-none-any.whl
Installing chardet-4.0.0-py2.py3-none-any.whl to c:\jython2.7.2\lib\site-packages
Adding chardet 4.0.0 to easy-install.pth file
Installing chardetect-script.py script to C:\jython2.7.2\bin
Installing chardetect.exe script to C:\jython2.7.2\bin

Installed c:\jython2.7.2\lib\site-packages\chardet-4.0.0-py2.7.egg
Searching for certifi>=2017.4.17
Reading https://pypi.org/simple/certifi/
Downloading https://files.pythonhosted.org/packages/05/1b/0a0dece0e8aa492a6ec9e4ad2fe366b511558cdc73fd3abc82ba7348e875/certifi-2021.5.30-py2.py3-none-any.whl#sha256=50b1e4f8446b06f41be7dd6338db18e0990601dce795c2b1686458aa7e8fa7d8
Best match: certifi 2021.5.30
Processing certifi-2021.5.30-py2.py3-none-any.whl
Installing certifi-2021.5.30-py2.py3-none-any.whl to c:\jython2.7.2\lib\site-packages
Adding certifi 2021.5.30 to easy-install.pth file

Installed c:\jython2.7.2\lib\site-packages\certifi-2021.5.30-py2.7.egg
Searching for urllib3<1.27,>=1.21.1
Reading https://pypi.org/simple/urllib3/
Downloading https://files.pythonhosted.org/packages/5f/64/43575537846896abac0b15c3e5ac678d787a4021e906703f1766bfb8ea11/urllib3-1.26.6-py2.py3-none-any.whl#sha256=39fb8672126159acb139a7718dd10806104dec1e2f0f6c88aab05d17df10c8d4
Best match: urllib3 1.26.6
Processing urllib3-1.26.6-py2.py3-none-any.whl
Installing urllib3-1.26.6-py2.py3-none-any.whl to c:\jython2.7.2\lib\site-packages
writing requirements to c:\jython2.7.2\lib\site-packages\urllib3-1.26.6-py2.7.egg\EGG-INFO\requires.txt
Adding urllib3 1.26.6 to easy-install.pth file

Installed c:\jython2.7.2\lib\site-packages\urllib3-1.26.6-py2.7.egg
Finished processing dependencies for requests==2.26.0

Before:

$ jython -m pip list
←[33mDEPRECATION: A future version of pip will drop support for Python 2.7.←[0m
Package    Version
---------- -------
pip        19.1
setuptools 41.0.1

After:

$ jython -m pip list
←[33mDEPRECATION: A future version of pip will drop support for Python 2.7.←[0m
Package    Version
---------- ---------
certifi    2021.5.30
chardet    4.0.0
idna       2.10
pip        19.1
requests   2.26.0
setuptools 41.0.1
urllib3    1.26.6

Hope this helps.

3 Likes

:+1:

That got me past the sticking point and automatically pulled/built/installed all the requirements in my local site-lib.

Directly copying the *.egg directories over to the site-lib of my Ignition server didn’t work, but thankfully all the libraries were cleanly implemented in subdirectories of the .egg directories. So I just copied those directories into site-lib on my Ignition server and everything appears to work so far.

Is there a better method to move/install things from site-lib/*.egg on one setup to another?

1 Like

Good news everyone: If you are using pip and have been struggling, the Jython devs fixed the SNI issue in the main Jython code branch. I’ve updated the guide to reflect how to get it working using the bug fix. Take a look at the Using pip section of the guide.

I also made a few other improvements, adding an example for Flask (which is more popular than Bottle), and fleshing out the subprocess example a bit more to show passing arguments.

6 Likes