Description
The basilisp
executable does not include any local paths in the PYTHONPATH
by default, aside from those inherited from the environment. This can limit a developer's ability to access local namespaces, often leading to non-portable workarounds across different projects or platforms.
For instance, if you invoke the basilisp
executable from outside a project, it won't automatically search the current working directory to resolve namespaces. As a result, you wouldn't be able to require any local files unless additional configuration steps are made.
A workaround is to manually set the PYTHONPATH
inline with the basilisp
command, as suggested in issue #952. However, this approach has its limitations, particularly on Windows. On that platform, environment variables can only be set globally within the shell, not on a per-command basis like this:
PYTHONPATH=src basilisp run -n a
Additionally in a project, the method for configuring PYTHONPATH
through Python build tools can vary. For example, in a typical Basilisp project, code is located in the src/<project>
directory and tests are in the tests/<project>
directory. When using Poetry, the package configuration in pyproject.toml
specifies where the code to be packaged is located, usually src/<myproject>
:
[tool.poetry]
name = "project"
version = "0.1.0"
description = ""
authors = []
readme = "README.md"
packages = [
{ include = "project", from = "src" },
]
This setup adds /path/to/<myproject>/src
to the PYTHONPATH
after running poetry install
, via an entry created in <venv>/<python>/site-packages/<project>.pth
. Consequently, while the basilisp executable can access namespaces in src/
, it won't have access to those in the tests/
directory since the current working directory ./
isn't included in the PYTHONPATH
.
I couldn't find a straightforward way to add an extra local directory to PYTHONPATH
using Poetry outside of the packages
option. IMHO, developers shouldn't have to spend time figuring out hacks for this with any Python build tool either.
One potential solution for both standalone and project scenarios is for the basilisp
executable to automatically add the current working directory to the PYTHONPATH
. This behavior is consistent with the python interpreter, which, according to the Python sys.path documentation, prepends an empty string to sys.path
(representing the current working directory) when running code from the command line or REPL.
However, the basilisp
executable currently does not include the empty string in the PYTHONPATH
. Instead, it prepends the directory where the basilisp
executable resides (e.g., /home/user/.cache/pypoetry/virtualenvs/myproject-8F5vs53K-py3.10/bin
).
To address this issue, one solution could be to have the basilisp
executable prepend the empty string ''
to the PYTHONPATH
on startup, while still inheriting other environment variables as usual. Another, more flexible solution familiar to Clojure developers would involve specifying local paths in the Clojure-like configuration file, in our case, basilisp.edn
, as proposed in issue #900.
What do you think? The second solution offers greater flexibility and familiarity to Clojure developers, while the first is simpler to implement but includes the entire current working directory in the PYTHONPATH
.
Thanks
Note: When the basilisp
script is invoked from within the Basilisp
project, it does include the empty string ''
in the PYTHONPATH
. This occurs because poetry install
sets up basilisp
as a shell script in the virtual environment, which ultimately calls the python
executable. As a result, the empty string ''
is prepended to the PYTHONPATH
by the Python interpreter. However, when Basilisp is installed as a package, the basilisp
script is a binary executable, which does not call python
and, therefore, does not prepend ''
to the PYTHONPATH
but the path where the executable resides.