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
[RFC 0024] Python: scope package set #24
Conversation
The purpose of the package set is to provide a set of compatible libraries that | ||
can be used for development purposes and as dependencies by Python applications. | ||
Applications are not considered part of the package set and their expressions | ||
shall thus also be placed elsewhere. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible for a package to provide both an application and a library at the same time in python?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, fixed in 473c470. That will require a new function toPythonApplication
which basically does the opposite of the current toPythonModule
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are there any real pure-Python applications that cannot be imported as a library?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If they don't put their modules in site-packages
, then it gets hard to import them. So, if they don't use setuptools/distutils/flit, that typically is the case.
However, I don't think it is important whether it is technically possible, but whether it is meant to. I would argue that upstream application developers typically use setuptools
to make it easier to distribute and that it is therefore just an implementation detail.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with your examples where there is a technical distinction. But what is gained by relying on intent when there is no technical hard distinction? If it is built just like a Python library, and it can be used as a Python library, and it can be generated by pypi2nix
and copied into the package set with a minimal cleanup — shouldn't it be duck-typed to a «Python package» and then maybe also aliased to the top-level namespace?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But what is gained by relying on intent when there is no technical hard distinction?
No practical gain. But as the language is an implementation detail it could be changed, whereas its purpose and thus its location in the tree would remain the same. Although, as you write, a pragmatic solution could be:
and then maybe also aliased to the top-level namespace?
In practice, though, there is actually another reason to have them separate: the additional constraints (pinning) typically imposed by applications (NixOS/nixpkgs#34775).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my experience, libraries can also have interesting version constraints.
I would call a complete rewrite, same or different language, a new package by the same team. Also, of packages I use, Mozilla Marionette (which is a Python package pythonPackages.marionette_driver
with no executables — so a library) still supports only Python2 and I wouldn't be surprised if it gets rewritten in Rust instead of updating to Python3.
recommended because: | ||
- applications can vary significantly in their dependencies, requiring different | ||
versions of packages, negating the use of a shared package set | ||
- of the reasons against using expression generators. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like a good idea given the current state of tooling. Hopefully we'll have something better than pypi2nix, maybe something more interactive, to build larger snapshots of packages working together.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like pypi2nix to eventually be able to support cascading of package sets (that are defined in Nix). Basically, have a main package set, and then secondary sets that build upon and extend the first one, without repeating its values. That would be useful for our applications.
👍 for defining/clarifying current practices. I think that it will be helpful for newcomers. The ideal outcome for the RFC would be some added docs in the nixpkgs manual. |
Thanks for codifying the policy you sometimes imply in your comments. |
|
||
Examples on the usage of application and library: | ||
- `scipy` is a collection of routines for scientific computing. It is used for development purposes or as a library and is therefore considered a *library* | ||
- `calibre` is a program for managing e-books that happens to be written in Python. The package is therefore considered an *application* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the other hand, https://manual.calibre-ebook.com/function_mode.html#the-power-of-function-mode-using-a-spelling-dictionary-to-fix-mis-hyphenated-words gives a snippet of code with
from calibre import replace_entities
from calibre import prepare_string_for_xml
Does this make Calibre both application and library?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. So, as I explained in my other comment, technically it is possible. And, in this case it seems it is supported upstream.
I think if there is demand we may consider it as both application and library. Otherwise, leave it as an application.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe pick an example that doesn't use setuptools
then?
Maintenance of the expressions takes effort. All expressions shall therefore | ||
have a maintainer. Packages that have no maintainer may be removed from the | ||
package set or marked as broken in case they seem to be unused, untouched in an | ||
extended period of time, or in whatever way cause additional work for other |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if there are no upstream updates and the package actually works well without them anyway?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it works fine and causes no additional maintenance then they likely would not be removed. But if the expression needs to be fixed because of say changes in dependencies then it will require maintenance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I surely agree with that. Maybe put the emphasis on this effort? «Packages that have no maintainer may be removed or marked as broken as soon as they require any additional maintenance effort, or there are any indications of dangerous bugs or vulnerabilities.»
application or a library. If both use cases are considered common, then the | ||
expression shall be part of the package set and a special alias shall we added | ||
to the top-level attribute set. This special attribute will mark the package as an | ||
application and shall be documented in the Nixpkgs manual. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we actually want to list all the libraries that also happen to provide useful tools in the manual? We don't explicitly mention that openssl
is both a tool and a library, after all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need better wording for that sentence. Basically, what I would like to say is that there shall be a function toPythonApplication
that is documented in the Nixpkgs manual that is to be used for the top-level attribute.
E.g.
calibre = with python.pkgs; toPythonApplication calibre;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What this function will actually do? Create .desktop
entries? What about pure-CLI tools?
And what you meant is «There shall be a function to perform additional post-installation steps specific to applications written in Python. This function shall be documented in the Nixpkgs manual.»?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. I've rewritten that section. Basically, it is important to distinguish applications from libraries because, when a library as part of a development environment needs to call an application, we don't want the dependencies of the application to be added to the Python environment. Or if one application written in Python calls another written in Python.
As this is an implementation detail (the use of propagatedBuildInputs
) I on purpose remain vague in this description.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that the need for propagation of dependencies is unlikely to change in Python2 or Python3, so even if it is an implementation detail, it could be mentioned somewhere, both in the manual (eventually) and in the RFC.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, there is the requiredPythonModules
function in python-packages.nix
which is also already used by python.buildEnv
and could also be used in buildPython*
. That could drop the need for propagatedBuildInputs
although it likely increases the evaluation time.
@FRidh would you like to go forward with this RFC to appoint a shepherd team, or does it need revisions first? |
@FRidh Closing this for now. Feel free to reopen if you still want to move forward. |
This pull request has been mentioned on Nix community. There might be relevant details there: https://discourse.nixos.org/t/scaling-the-python-package-set-in-nixpkgs/3749/1 |
Formalize the scope of the Python package set.
Work in progress as I consider the following additions:
Rendered