Python tix module #21643

Merged
merged 3 commits into from Jan 4, 2017

Projects

None yet

3 participants

@symphorien
Contributor
Motivation for this change

Being able to use the tkinter.tix python module (which is in the standard library).
This is done in three parts:

  • adding tk private headers to the dev output of the derivation (tcl private headers are already there) which are needed to build tix
  • adding a tix package
  • wrapping python to set the correct TIX_LIBRARY environment variable
Things done
  • Tested using sandboxing
    (nix.useSandbox on NixOS,
    or option build-use-sandbox in nix.conf
    on non-NixOS)
  • Built on platform(s)
    • NixOS
    • macOS
    • Linux
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nox --run "nox-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Fits CONTRIBUTING.md.

Regarding testing : I rebuilt my whole system with those versions of cpython (my laptop has not enough ram to build pypy) and it has been working fine since then. I could not test extensively all the packages impacted by those changes. And of course I checked that the tkinter.tix module works.

@mention-bot

@symphorien, thanks for your PR! By analyzing the history of the files in this pull request, we identified @FRidh, @domenkozar and @kragniz to be potential reviewers.

@FRidh FRidh self-assigned this Jan 4, 2017
@@ -121,7 +122,7 @@ let
buildInputs =
optional (stdenv ? cc && stdenv.cc.libc != null) stdenv.cc.libc ++
- [ bzip2 openssl zlib ]
+ [ bzip2 openssl zlib makeWrapper]
++ optionals stdenv.isCygwin [ expat libffi ]
++ [ db gdbm ncurses sqlite readline ]
++ optionals x11Support [ tcl tk xlibsWrapper libX11 ]
@FRidh
FRidh Jan 4, 2017 Member

++ optionals x11Support [ tcl tk libX11 xproto tix ]

Then you should be able to get rid of the wrapper. At least, I made the change and it seems to work.

@symphorien
symphorien Jan 4, 2017 Contributor

Not sure to understand well : Do you want me to put makeWrapper in [ tcl tk libX11 xproto tix ] ?

@FRidh
FRidh Jan 4, 2017 edited Member

no, put tix there like I wrote.
Ah, I made the change in python 3.5 expression, so that's why it looks slightly different.

@symphorien
symphorien Jan 4, 2017 Contributor

I tried this http://xelpaste.net/2J0wKk but it doesn't work for me :

    self.tk.eval('package require Tix')
_tkinter.TclError: can't find package Tix
+ license = with licenses; [
+ bsd2 # tix
+ gpl2 # patches from portage
+ ];
@FRidh
FRidh Jan 4, 2017 Member

would you like to maintain this package?

@symphorien
symphorien Jan 4, 2017 Contributor

No.

pkgs/top-level/all-packages.nix
+ tix = tix-8_6;
+
+ tix-8_6 = callPackage ../development/libraries/tix { };
+ tix-8_5 = callPackage ../development/libraries/tix {
@FRidh
FRidh Jan 4, 2017 Member

We only use tix-8_6, so we don't need tix-8_5 and can just use

tix = callPackage ...
@FRidh
Member
FRidh commented Jan 4, 2017

I don't think this will be a mass rebuild (tk isn't used much) but even so please rebase against staging.

@symphorien symphorien tk: add private headers to /include
those are necessary to build some extensions like tix
87ef971
@symphorien symphorien changed the base branch to NixOS:staging from NixOS:master Jan 4, 2017
@FRidh
Member
FRidh commented Jan 4, 2017 edited

Indeed, you are right. I checked the source code and it always tries to find the library using an environment variable.

We shouldn't use a wrapper if we can do so without. I think we can patch the code to point to the Tix library.

The following (Python 3.5) doesn't seem to be sufficient yet

  postPatch = optionalString x11Support ''
    substituteInPlace "Lib/tkinter/tix.py" --replace "os.environ.get('TIX_LIBRARY')" "'${tix}/lib'"
  '';

because

>>> import tkinter.tix
>>> root = tkinter.tix.Tk()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/nix/store/p6m8pxyw6njqfk82bdgj08w8pdrhq17h-python3-3.5.2/lib/python3.5/tkinter/tix.py", line 221, in __init__
    self.tk.eval('package require Tix')
_tkinter.TclError: Can't find a usable Init.tcl in the following directories: 
    /nix/store/aqfcswnix9ayq1jwrh931gjimnwxc7mq-tcl-8.6.6/lib/tcl8.6/Tix8.4.3 /nix/store/aqfcswnix9ayq1jwrh931gjimnwxc7mq-tcl-8.6.6/lib/Tix8.4.3 /nix/store/p6m8pxyw6njqfk82bdgj08w8pdrhq17h-python3-3.5.2/lib/Tix8.4.3 /nix/store/8djjhdby3grc0zq90bl5qg7ckzvgrmfd-tk-8.6.6/lib/tk8.6/Tix8.4.3 /nix/store/8djjhdby3grc0zq90bl5qg7ckzvgrmfd-tk-8.6.6/lib/tk8.6/ttk/Tix8.4.3 /nix/store/p6m8pxyw6njqfk82bdgj08w8pdrhq17h-python3-3.5.2/bin/Tix8.4.3 /nix/store/95y3xa78f7ksdy9hwks01axhw738km85-tix-8.4.3/Tix8.4.3 /nix/store/lib/Tix8.4.3 /nix/store/p6m8pxyw6njqfk82bdgj08w8pdrhq17h-python3-3.5.2/library

Note that when using this method we should copy tix.py in pythonPackages.tkinter.

The Python docs write

If this fails, you have a Tk installation problem which must be resolved before proceeding. Use the environment variable TIX_LIBRARY to point to the installed Tix library directory, and make sure you have the dynamic object library (tix8183.dll or libtix8183.so) in the same directory that contains your Tk dynamic object library (tk8183.dll or libtk8183.so). The directory with the dynamic object library should also have a file called pkgIndex.tcl (case sensitive), which contains the line:

@symphorien
Contributor

The patch you proposed should have worked, but there was a mistake in the way I packaged tix for it to work. I force pushed something which is close to what you proposed.

@FRidh

Great. I see you want to keep support for TIX_LIBRARY? That seems reasonable.

@@ -113,6 +113,7 @@ let
# will think the wrapper is the original. As long as the wrapper has
# the same path as the original, this is OK.
wrapProgram "$out/pypy-c/pypy-c" \
+ --set TIX_LIBRARY ${tix}/lib \
@FRidh
FRidh Jan 4, 2017 Member

grepping the PyPy source code gave me the following file that needs to be patched

lib-python/2.7/lib-tk/Tix.py:        tixlib = os.environ.get('TIX_LIBRARY')
@FRidh
Member
FRidh commented Jan 4, 2017

There is one more challenge though. The default Python python won't have the reference to Tix, which is what we want. pythonFull will have the reference, that is fine, but pythonFull is deprecated in favor of using python.withPackages(ps: [ps.tkinter]). And the latter won't work yet

$ nix-shell -p 'python.withPackages(ps: [ps.tkinter])' --run "python -c 'import Tix; Tix.Tk()'" -I nixpkgs=.
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/nix/store/i1m970i9mbrk0aqr5z5rf0rfx8jihmy4-python-2.7.13-env/lib/python2.7/lib-tk/Tix.py", line 222, in __init__
    self.tk.eval('package require Tix')
_tkinter.TclError: can't find package Tix

because it uses the interpreter from python and the _tkinter module from pythonFull. (Note that I just saw it also links to the Python interpreter from pythonFull which is a bit of a problem.)

@symphorien
Contributor
symphorien commented Jan 4, 2017 edited

I forgot pypy, that should be fixed.
Regarding pythonFull, do you mean that the x11support argument is to be eventually removed ?

@FRidh
Member
FRidh commented Jan 4, 2017

Regarding pythonFull, do you mean that the x11support value is to be eventually removed ?

The parameter will stay; just the attibute pkgs.pythonFull is deprecated. The parameter is used to actually be able to build pythonPackages.tkinter.

@FRidh
FRidh approved these changes Jan 4, 2017 View changes

(Note that I just saw it also links to the Python interpreter from pythonFull which is a bit of a problem.)

This has been fixed now in e276f59

@symphorien This PR looks good to me as it is. Unfortunately tix won't work yet with python.withPackages(ps: [ps.tkinter]). Even so I think this can go in now.

@FRidh FRidh merged commit a301865 into NixOS:staging Jan 4, 2017

1 check was pending

continuous-integration/travis-ci/pr The Travis CI build is in progress
Details
@domenkozar domenkozar referenced this pull request Jan 4, 2017
Open

Python ecosystem improvements (placeholder issue) #1819

9 of 36 tasks complete
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment