Pyenv-installed Python creates virtualenv with empty include dir, no python-config in bin - virtualenv

Note: There are several similar questions, which I have seen and read. None of them are the precise problem I'm having, and none of their answers work for me.
I have installed several Python versions (Python 2.7, 3.8, 3.9, and 3.10) on my macOS Ventura system using Pyenv. The installed directories include a python-config file in /bin and an /include directory with many header files, so I do not need to install python-devel or similar:
$ ls -al /Users/williamsn/.pyenv/versions/3.10.9/bin/*-config
lrwxr-xr-x 1 williamsn staff 17 Dec 19 17:24
/Users/williamsn/.pyenv/versions/3.10.9/bin/python-config -> python3.10-config
lrwxr-xr-x 1 williamsn staff 17 Dec 19 17:24
/Users/williamsn/.pyenv/versions/3.10.9/bin/python3-config -> python3.10-config
-rwxr-xr-x 1 williamsn staff 2073 Dec 19 17:24
/Users/williamsn/.pyenv/versions/3.10.9/bin/python3.10-config
$ ls -al /Users/williamsn/.pyenv/versions/3.10.9/include/python3.10/
total 1192
drwxr-xr-x 86 williamsn staff 2752 Dec 19 17:24 .
drwxr-xr-x 3 williamsn staff 96 Dec 19 17:24 ..
-rw-r--r-- 1 williamsn staff 3224 Dec 19 17:24 Python.h
...
-rw-r--r-- 1 williamsn staff 3026 Dec 19 17:24 import.h
...
-rw-r--r-- 1 williamsn staff 48878 Dec 19 17:24 pyconfig.h
...
-rw-r--r-- 1 williamsn staff 2863 Dec 19 17:24 weakrefobject.h
As a best practice, I work exclusively in virtualenvs to keep the base Python installation clean and pristine. I create my virtualenvs using the venv module built in to Python 3:
$ python3.10 -m venv my_venv
After doing so, there are two problems:
The my_venv/include directory is empty (does not contain the python3.10 directory or any of the header files from the parent Python and does not symlink to the parent Python)
There is no python-config / python3-config / python3.10-config in my_venv/bin.
So, for things requiring the Python headers:
If it tries to find the headers using python-config (which many projects do), it will fail.
If it tries to find the headers using the Python prefix and adding /include to it (which many projects do, notably Boost), it will fail.
If it tries to find the headers by importing sysconfig and calling sysconfig.get_paths(), it will succeed, albeit with paths outside the virtualenv.
Now, on a case-by-case basis, I can work around this, and already have. I can manually copy over python_config and then either export CPATH to add /Users/williamsn/.pyenv/versions/3.10.9/include/python3.10 or modify the virtualenv to symlink to /Users/williamsn/.pyenv/versions/3.10.9/include. These work, but they don't seem right to me. I can't make a global workaround anywhere (such as exporting CPATH in my Bash profile), because I'm working with multiple Python versions, and I'd end up with the wrong headers half the time. It seems to me like a virtualenv that has an empty include directory and is missing python-config when its parent has a full include directory and contains python-config is a broken virtualenv.
Is there an option I'm missing to include these pieces? Is this a bug I need to file against Python/venv?

Related

How to reset VSCode extensions for a workspace

I was having issues with a workspace so I tried disabling all of extensions for it. Then the only option was to enable all extensions for the workspace. I have extensions globally configured to be off or on, but I'm not sure how to get a workspace to reset to the global extensions now?
I know I can open a new window up and start manually enable/disabling the extensions in my workspace to match the new fresh window. The problem is that it would then have its own workspace extensions defined, so if I toggled one at a global level it would still have an override.
I also tried deleting the .vscode folder in the workspace, but that doesn't seem to change the extensions for the workspace.
It's not a great method but I guess this works with a lot of manual leg work.
Enable all extensions for workspace
Open a new VSCode window
Goto extensions and filter by #disabled
You can also do #enabled and disable all extensions in the first step if you have more disabled than enabled.
Now you have a list you can target. Just click Disable instead of Disable for Workspace.
I believe this should get your workspace back to normal. There has to be an easier way though. You may also have to toggle enabled extensions to disabled and then back to enabled in case it has a workspace override for them -- I didn't check how it would behave if a new window disabled the extension whether or not it would keep staying on.
I've found a way to reset all settings for a given workspace.
First, navigate to ~/.config/Code/User/workspaceStorage. Inside there, you'll find a lot of folders with seemingly random names. Each folder seems to represent one workspace.
# cd ~/.config/Code/User/workspaceStorage
# ls -la
total 156
drwxr-xr-x 39 micael micael 4096 Feb 18 15:00 .
drwxr-xr-x 6 micael micael 4096 Nov 15 13:05 ..
drwxr-xr-x 2 micael micael 4096 Jan 18 16:09 0cf549e23d37c32c70a7e30998ade1fe
drwxr-xr-x 3 micael micael 4096 Dec 29 17:42 1b637cb30f6c3acc9273df20c84be7aa
drwxr-xr-x 2 micael micael 4096 Jan 17 22:09 2010f3fb6dbb2574f12a5ba614b3b136
drwxr-xr-x 2 micael micael 4096 Feb 18 15:01 a09a9ab934662794ac48730fc950a654
...
Inside each folder, there's a workspace.json file that contains the path of the folder your workspace was created from.
We can use grep to quickly search all those folders for a matching string:
grep -r 'myfolder' ., where myfolder should be the name of the folder your workspace is using.
In this example, my workspace was created from a folder called python-playground:
# grep -r 'python-playground' .
./a09a9ab934662794ac48730fc950a654/workspace.json: "folder": "file:///home/micael/projects/python-playground"
grep: ./a09a9ab934662794ac48730fc950a654/state.vscdb: binary file matches
grep: ./a09a9ab934662794ac48730fc950a654/state.vscdb.backup: binary file matches
In my case, the folder I'm looking for is ./a09a9ab934662794ac48730fc950a654.
You'll likely get a few results, all inside the same folder. Let's first take a look inside the folder:
# ls -la a09a9ab934662794ac48730fc950a654
total 64
drwxr-xr-x 2 micael micael 4096 Feb 18 15:01 .
drwxr-xr-x 39 micael micael 4096 Feb 18 15:00 ..
-rw-r--r-- 1 micael micael 28672 Feb 18 15:01 state.vscdb
-rw-r--r-- 1 micael micael 24576 Feb 18 15:01 state.vscdb.backup
-rw-r--r-- 1 micael micael 64 Feb 18 15:00 workspace.json
# cat a09a9ab934662794ac48730fc950a654/workspace.json
{
"folder": "file:///home/micael/projects/python-playground"
}%
Now, we can either remove this folder or move it elsewhere. Make sure to close VSCode before doing so.
# rm -rf a09a9ab934662794ac48730fc950a654

Postgresql could not load library

after days of regular fight with postgis I stuck on this:
postgres=# CREATE EXTENSION postgis; ERROR: could not load library
"/usr/pgpro-9.6/lib/rtpostgis-2.4.so": libgdal.so.20: cannot open
shared object file: No such file or directory
and have no idea how to pass it, because library path is correct...
[combat#urpordfinal ~]$ ls -alt /usr/pgpro-9.6/lib/ total 13080
-rwxr-xr-x 1 root root 1440056 Apr 23 11:52 postgis_topology-2.4.so
drwxr-xr-x 5 root root 8192 Apr 23 11:52 .
-rwxr-xr-x 1 root root 1878728 Apr 23 11:52 rtpostgis-2.4.so
I'm running pgsql 9.6.8 and psotgis build from source
You have to make sure that libgdal.so.20 is on the shared library path.
Find out where the library is and add that directory to the shared library path.
On Linux, you would normally do that by adding the directory to /etc/ld.so.conf (or, better, to a PostGIS configuration file in /etc/ld.so.conf.d) and running ldconfig.

Pydev tags import as “unresolved import” all compiled extensions

PyDev with Python3.5 seems unable to recognize imports from c-compiled extensions, including packages compiled via Cython.
I am working on an up-to-date debian/stretch machine with a stripped-down self-installed (in home dir) Eclipse/Neon with PyDev added via update site, if it matters.
I have both "Python 2.7.13" and "Python 3.5.2+" installed.
One of the problematic packages is lxml. I installed the debian packages and also tried installing manually via pip (and re-created the interpreter in eclipse afterwards to ensure full finding). In all cases packages do work.
In Python2 everything works as advertised.
Under Python3 PyDev flags from lxml import etree as error (but resulting program works):
Unresolved import: etree richiedi_certificato_dispositivo.py /trasmissione-telematica/Serializzazione line 8 PyDev Problem
Note: I can import lxml with no error, but then any access to lxml.etree... will be flagged in error. Data completion is consistent (i.e.: etree won't be in the offered list).
lxml is installed in the usual location:
mcon#vocore:~$ ls -l /usr/lib/python3/dist-packages/lxml
total 2156
-rw-r--r-- 1 root root 8152 Sep 5 2014 builder.py
-rw-r--r-- 1 root root 3366 May 5 2016 cssselect.py
-rw-r--r-- 1 root root 18387 May 5 2016 doctestcompare.py
-rw-r--r-- 1 root root 7641 Sep 25 2011 ElementInclude.py
-rw-r--r-- 1 root root 9490 Aug 20 06:48 _elementpath.py
-rw-r--r-- 1 root root 1710088 Aug 24 10:14 etree.cpython-35m-x86_64-linux-gnu.so
drwxr-xr-x 3 root root 4096 Jan 3 08:58 html
drwxr-xr-x 3 root root 4096 Jan 3 08:58 includes
-rw-r--r-- 1 root root 551 Oct 7 2012 __init__.py
drwxr-xr-x 4 root root 4096 Jan 3 08:58 isoschematron
-rw-r--r-- 1 root root 17450 Aug 20 06:48 lxml.etree_api.h
-rw-r--r-- 1 root root 8902 Aug 20 06:48 lxml.etree.h
-rw-r--r-- 1 root root 366440 Aug 24 10:14 objectify.cpython-35m-x86_64-linux-gnu.so
drwxr-xr-x 2 root root 4096 Jan 3 08:58 __pycache__
-rw-r--r-- 1 root root 92 Sep 5 2014 pyclasslookup.py
-rw-r--r-- 1 root root 8531 Nov 20 2014 sax.py
-rw-r--r-- 1 root root 230 Sep 25 2011 usedoctest.py
mcon#vocore:~/trasmissione-telematica$
As You can see etree is in a shared lib, as is objectify; a quick check shows also objectify is not handled by PyDev. I checked a few other "c-extension" packages (e.g.: import pycurl and from Crypto.Util import strxor) with the same result, so it seems a problem with "C" extensions.
Have you tried to put the offending packages in the forced builtins (as described in http://www.pydev.org/manual_101_interpreter.html)?
If that doesn't work, do you have some error in your error log? (see http://www.pydev.org/faq.html#PyDevFAQ-HowdoIReportaBUG%3F for details on getting it)

Perl: strange behaviour of glob with files greater than 2 GB

I'm simply trying to get a list of filenames given a path with wildcard.
my $path = "/foo/bar/*/*.txt";
my #file_list = glob($path);
foreach $current_file (#file_list) {
print "\n- $current_file";
}
Mostly this works perfectly, but if there's a file greater than 2GB, somewhere in one of the /foo/bar/* subpaths, the glob returns an empty array without any error or warning.
If I remove the file file or add a character/bracket sequence like this:
my $path = "/foo/bar/*[0-9]/*.txt";
or
my $path = "/foo/bar/*1/*.txt";
then the glob works again.
UPDATE:
Here's an example (for a matter of business policy I had to mask the pathname):
[root]/foo/bar # ls -lrt
drwxr-xr-x 2 root system 256 Oct 11 2006 lost+found
drwxr-xr-x 2 root system 256 Dec 27 2007 abc***
drwxr-xr-x 2 root system 256 Nov 12 15:32 cde***
-rw-r--r-- 1 root system 2734193149 Nov 15 05:07 archive1.tar.gz
-rw-r--r-- 1 root system 6913743 Nov 16 05:05 archive2.tar.gz
drwxr-xr-x 2 root system 256 Nov 16 10:00 fgh***
[root]/foo/bar # /home/user/test.pl
[root]/foo/bar #
Removing the >2GB file (or globbing with "/foo/bar/[acf]/" istead of "/foo/bar//")
[root]/foo/bar # ls -lrt
drwxr-xr-x 2 root system 256 Oct 11 2006 lost+found
drwxr-xr-x 2 root system 256 Dec 27 2007 abc***
drwxr-xr-x 2 root system 256 Nov 12 15:32 cde***
-rw-r--r-- 1 root system 6913743 Nov 16 05:05 archive2.tar.gz
drwxr-xr-x 2 root system 256 Nov 16 10:00 fgh***
[root]/foo/bar # /home/user/test.pl
- /foo/bar/abc***/heapdump.phd.gz
- /foo/bar/cde***/javacore.txt.gz
- /foo/bar/fgh***/stuff.txt
[root]/foo/bar #
Any suggestion?
I'm working with:
Perl 5.8.8
Aix 5.3
The filesystem is a local jfs.
In the absence of a proper answer you're going to want a work-around. I'm guessing you've hit some platform-specific bug in the glob() implementation of 5.8.8
I had a quick look at the source on CPAN but my C is too rusty to spot anything useful.
There have been lots of changes to that module though, so a bug may well have been reported and fixed. You're not even on the last release of 5.8 - there's a 5.8.9 out there which mentions updates to AIX compatibility and File::Glob.
I'd test this by installing local::lib if you haven't already and then perhaps cpanm and try updating File::Glob - see what that does. You might need to download the files by hand from e.g. here
If that solves the problem then you can either deploy updates to the required systems, or you'll have to re-implement the bits of glob() you want. Which is going to depend on how complex your patterns get.
If it doesn't solve the problem then at least you'll be able to stick some printf's into the code and see what it's doing.
Hopefully someone will post a real answer and make this redundant about 5 minutes after I click "Post Your Answer" though.
I've never used the new Glob function before, so i cant comment on benefits/problems, but it seems quite a lot of people have had issues using it: see => https://stackoverflow.com/search?q=perl+glob&submit=search for some questions and possible solutions.
IF you don't mind trying out something else:
Here is my tried and tested 'old school' perl solution i have used in countless projects:
my $path = "/foo/bar/";
my #result_array = qx(find $path -iname '*.txt'); #run the system find command
If you - for whatever reason prefer not to run a system command from within your script, then lookup the built in Find::Perl Module instead: http://search.cpan.org/~dom/perl-5.12.5/lib/File/Find.pm
good luck

Regarding Perl DBD::Oracle installation in local directory

I want to connect with the oracle database from a perl script in solaris servier. Able to see DBI is installed but not DBD::Oracle in the current perl version 5.8.4. I dont have root acess and working on my home user id. Download the DBD-Oracle-1.50 and unzipped in the local directory where my perl script exists. I want to copy the DBD Oracle library files into a custom directory and run the script since i dont have root acess. When i read the install script in the DBD-Oracle-1.50 it's says for manuall install i need to run the below scripts . Since i dont have root access i want to copy the library modules into the local directory. Not sure how to tell these scripts to install it in the local directory where my perl script exists.
Does installing DBI and DBD in a custom directory under my user id makes it work properly. Do those modules require root access to work properly? To use DBD::Oracle does oracle needs to be installed in server. My Understanding Oracle driver DBD::Oracle should take care of it.
perl Makefile.PL
make && make test
make install
> ls -tlr /usr/perl5/vendor_perl/5.8.4/sun4-solaris-64int total 956
> -rwxr-xr-x 1 root bin 15161 Mar 26 2005 Roadmap.pod
> -rwxr-xr-x 1 root bin 1048 Sep 5 2006 TASKS.pod
> -rwxr-xr-x 1 root bin 289343 Jun 26 2007 DBI.pm
> -rwxr-xr-x 1 root bin 4608 Jun 12 2008 goferperf.pl
> -rwxr-xr-x 1 root bin 1356 Jun 12 2008 dbixs_rev.pl
> -rwxr-xr-x 1 root bin 58386 Apr 3 2010 SNMP.pm drwxr-xr-x 3 root bin 7 Oct 13 2010 NetSNMP
> drwxr-xr-x 2 root bin 3 Oct 13 2010 Win32 drwxr-xr-x
> 8 root bin 19 Oct 13 2010 DBI drwxr-xr-x 2 root
> bin 4 Oct 13 2010 Bundle drwxr-xr-x 6 root other
> 6 Oct 13 2010 auto drwxr-xr-x 3 root bin 11 Oct 13
> 2010 DBD
>
> ls -ltr /usr/perl5/vendor_perl/5.8.4/sun4-solaris-64int/DBD total 543
> -rwxr-xr-x 1 root bin 111586 May 6 2006 Pg.pm
> -rwxr-xr-x 1 root bin 28785 Sep 27 2006 Proxy.pm
> -rwxr-xr-x 1 root bin 7937 Jan 25 2007 Sponge.pm
> -rwxr-xr-x 1 root bin 42836 Feb 6 2007 DBM.pm
> -rwxr-xr-x 1 root bin 19882 Mar 28 2007 File.pm
> -rwxr-xr-x 1 root bin 12051 May 10 2007 ExampleP.pm
> -rwxr-xr-x 1 root bin 43586 May 14 2007 Gofer.pm
> -rwxr-xr-x 1 root bin 3761 Jun 15 2007 NullP.pm drwxr-xr-x 4 root bin 4 Oct 13 2010 Gofer
If DBI is already installed, you should only need to install DBD::Oracle, though you might want to install a later version of DBI. You can install DBD::Oracle under your home directory, then set the PERL5LIB environment variable to that directory (or to include that directory). The long way to install is:
perl Makefile.PL PREFIX=~/perl #Or whatever sub-directory you like
make
make test
make install
Then include at least "~/perl/lib;~/perl/lib/site_perl" in PERL5LIB before running your programs (or include a 'use lib" in your programs).
You can also set certain environment variables like PERL_MM_OPT and PERL_MB_OPT so that you don't have to specify the PREFIX= on the command line (see docs for ExtUtils::MakeMaker and Module::Build). I also recommend cpanm and setting PERL_CPANM_HOME to something under your home directory.
Perl modules can be very well installed in a custom directory. This situation usually arises when you don't have root access to install the PM. Once you have installed DBI and DBD in your custom folder there are several different ways to make sure that perl is aware of this installation.
1. Set the environment variable PERL5LIB
Perl will look for modules in the directories specified in PERL5LIB environment variable before looking in the standard library and current directory, so you can set this variable to locate your modules.
The syntax is the same you use for the PATH environment variables, so you separate the directories with colons on unix and with a semicolon on Windows.
Example:
# unix, bourne shell
PERL5LIB=/home/path/lib:/usr/another/path/lib; export PERL5LIB
Be aware that scripts running with -T option (taint checks) do not use that variable, so in those cases this option won't work.
2. Use '-I' command line parameter
The syntax should be something like:
perl -I /home/path/lib -I /usr/another/lib script.pl
3. Add the library path in your script
The command for including the path in your script is: use lib "path".
Notice that this statement prepends "path" to the #INC array, so it's basically the same as unshift #INC, "path"
Example:
#!/usr/bin/perl
use lib "/home/path/lib";
use lib "/usr/another/lib";