How to handle ModuleNotFoundError: No module named 'distutils.msvccompiler' on Mac OSX (Intel) using f2py?

Samuel H Dupree Jr <[email protected]> Sun, 4 Jan 2026 20:18:37 -0500
Newsgroups gmane.comp.python.numeric.general
Organization XrayDeltaOne
Message-ID <[email protected]>
I am resurrecting a Python program I wrote a few years under Python 3.9. 
I'm presently:

  * Running Python 3.11 under Mac OSX Sequoia (ver. 15.7.1)
  * Using NumPy version 1.26.4
  * Running on an Intel (x86-64) Mac Pro Desktop (2019)
  *

The program uses a Fortran 77 subroutine that was wrapped using f2py 
when I running Python 3.9. However, when I attempt to wrap that same 
subroutine (the source code is attached to this note) using f2py in 
Python 3.11, I get the following error message.


(base) user@Mac-Pro accgravityfiled_builder_f2py % */f2py -c 
accgravityfield.f -m accgravityfield /*
Traceback (most recent call last):
   File "/Users/user/opt/anaconda3/bin/f2py", line 8, in <module>
     sys.exit(main())
              ^^^^^^
   File 
"/Users/user/opt/anaconda3/lib/python3.11/site-packages/numpy/f2py/f2py2e.py", 
line 766, in main
     run_compile()
   File 
"/Users/user/opt/anaconda3/lib/python3.11/site-packages/numpy/f2py/f2py2e.py", 
line 594, in run_compile
     build_backend = f2py_build_generator(backend_key)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File 
"/Users/user/opt/anaconda3/lib/python3.11/site-packages/numpy/f2py/_backends/__init__.py", 
line 6, in f2py_build_generator
     from ._distutils import DistutilsBackend
   File 
"/Users/user/opt/anaconda3/lib/python3.11/site-packages/numpy/f2py/_backends/_distutils.py", 
line 3, in <module>
     from numpy.distutils.core import setup, Extension
   File 
"/Users/user/opt/anaconda3/lib/python3.11/site-packages/numpy/distutils/core.py", 
line 24, in <module>
     from numpy.distutils.command import config, config_compiler, \
   File 
"/Users/user/opt/anaconda3/lib/python3.11/site-packages/numpy/distutils/command/config.py", 
line 19, in <module>
     from numpy.distutils.mingw32ccompiler import generate_manifest
   File 
"/Users/user/opt/anaconda3/lib/python3.11/site-packages/numpy/distutils/mingw32ccompiler.py", 
line 27, in <module>
     from distutils.msvccompiler import get_build_version as 
get_build_msvc_version
ModuleNotFoundError: No module named 'distutils.msvccompiler'
(base) user@Mac-Pro accgravityfiled_builder_f2py %


As for gfortran is concerned:


(base) user@Mac-Pro accgravityfiled_builder_f2py % gfortran -v
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=/usr/local/Cellar/gcc/15.2.0/bin/../libexec/gcc/x86_64-apple-darwin24/15/lto-wrapper
Target: x86_64-apple-darwin24
Configured with: ../configure --prefix=/usr/local/opt/gcc 
--libdir=/usr/local/opt/gcc/lib/gcc/current --disable-nls 
--enable-checking=release --with-gcc-major-version-only 
--enable-languages=c,c++,objc,obj-c++,fortran --program-suffix=-15 
--with-gmp=/usr/local/opt/gmp --with-mpfr=/usr/local/opt/mpfr 
--with-mpc=/usr/local/opt/libmpc --with-isl=/usr/local/opt/isl 
--with-zstd=/usr/local/opt/zstd --with-pkgversion='Homebrew GCC 15.2.0' 
--with-bugurl=https://github.com/Homebrew/homebrew-core/issues 
--with-system-zlib --build=x86_64-apple-darwin24 
--with-sysroot=/Library/Developer/CommandLineTools/SDKs/MacOSX15.sdk
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 15.2.0 (Homebrew GCC 15.2.0)
(base) user@Mac-Pro accgravityfiled_builder_f2py %


I have two questions:

 1. Why is f2py in a Mac OSX Intel based environment attempting to
    import '*/distutils.msvccompiler/*' that is required for Windows'
    environment only?
 2. What do I need to do to eliminate this problem?

Any thoughts?

Sam Dupree

_______________________________________________
NumPy-Discussion mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/numpy-discussion.python.org
Member address: [email protected]
accgravityfield.f (text/plain, 6.7 KB)
      subroutine accgravityfield( Ndim, Mdim, NMAX, Nm, Ae, GM,
     1                          C, S, X, Ac)
C -------------------------------------------------------------------------
C
C  Purpose: To compute geopotential acceleration
C  -------
C
C  Inputs:
C  ------
C     Ndim  I*4 max. degree (row dimension od C and S matrices)
C     Mdim  I*4 max. order loaded (column dimension C and S matrices)
C     NMAX  I*4 max. degree and order loaded
C       Nm  I*4 desired degree and order (Nm <= NMAX)
C       Ae  R*8 mean equatorial radius of the model [m]
C       GM  R*8 Earth gravitational constant [m**3/s**2]
C        C  R*8 array (0:Ndim,0:Mdim) Harmonic coefficients C(n,m)
C        S  R*8 array (0:Ndim,0:Mdim) Harmonic coefficients S(n,m)
C        X  R*8 array (3) ECEF cartesian coordinates [m]
C
C  Outputs:
C  -------
C       Ac  R8 array (3) with geopotential (x, y, z) accelerations [m/s**2]
C
C  Author: HKK - INPE - May 2012 - Version 1.0
C
C  References:
C  ---------- 
C
C    Kuga, H.K.; Carrara, V. "Fortran- and C-codes for higher order
C      and degree geopotential computation." 
C      www.dem.inpe.br/~hkk/software/high_geopot.html
C      Last access May 2012.
C
C -----------------------------------------------------------------------

      IMPLICIT NONE

      INTEGER NMAX, Nm, Ndim, Mdim
C      REAL*8 Ae, GM, C(0:NMAX,0:Nm), S(0:NMAX,0:Nm), x(3), Ac(3)
      DOUBLE PRECISION Ae, GM, C(0:Ndim,0:Mdim), S(0:Ndim,0:Mdim)
      DOUBLE PRECISION X(3), Ac(3)

C Locals
      INTEGER n, m
      DOUBLE PRECISION r, q, t, u, tf, al, sl, cl, Gmr
      DOUBLE PRECISION pn(0:Nm), qn(0:Nm)
      DOUBLE PRECISION Pnm, dPnm, anm, bnm, fnm
      DOUBLE PRECISION am, an, Pnm1m, Pnm2m, sm, cm, sml, cml
      DOUBLE PRECISION qC, qS, Xc, Xs, Xcf, Xsf, Xcr, Xsr, Vl, Vf, Vr
      DOUBLE PRECISION J2, J3, J4, PInm
C      DOUBLE PRECISION Omega

C
Cf2py   intent(in) Ndim, Mdim, NMAX, Nm, Ae, GM, C, S, X
Cf2py   intent(out) Ac
Cf2py   depend(Ndim,Mdim) C, S
C

C Auxiliary variables
      r   = sqrt(X(1)*X(1) + X(2)*X(2) + X(3)*X(3))
      q   = Ae / r
      t   = X(3) / r  ! sin (lat)
      u   = sqrt (1.d0 - t*t)
      tf  = t/u        ! tan (lat)
      al  = atan2( X(2), X(1) )
      sl  = sin (al)            ! sin (long)
      cl  = cos (al)            ! cos (long)
      Gmr = GM / r

      
C Process J2, J3, J4 accelerations

      Ac(1) = -GM * X(1) / r**3
      Ac(2) = -GM * X(2) / r**3
      Ac(3) = -GM * X(3) / r**3
      
      if( Nm .eq. 0 ) then
      
         if( NMAX .ge. 2 ) then
            
            PInm =  dsqrt( 1.d0 / 5.d0 )
            J2 = -C(2,0) / PInm
            
            Ac(1) = Ac(1) - J2*(3.d0/2.d0)*(Gmr/r)*(q**2)*
     1                         (X(1)/r)*(1.d0-5.d0*(t**2))
            
            Ac(2) = Ac(2) - J2*(3.d0/2.d0)*(Gmr/r)*(q**2)*
     1                         (X(2)/r)*(1.d0-5.d0*(t**2))
            
            Ac(3) = Ac(3) - J2*(3.d0/2.d0)*(Gmr/r)*(q**2)*
     1                         (X(3)/r)*(3.d0-5.d0*(t**2))
            
         end if
      
         if( NMAX .ge. 3 ) then
            
            PInm = dsqrt( 1.d0 / 7.d0 )
            J3 = -C(3,0) / PInm
            
            Ac(1) = Ac(1) - J3*(5.d0/2.d0)*(Gmr/r)*(q**3)*
     1                         (X(1)/r)*(3.d0*t-7.d0*(t**3))
            
            Ac(2) = Ac(2) - J3*(5.d0/2.d0)*(Gmr/r)*(q**3)*
     1                         (X(2)/r)*(3.d0*t-7.d0*(t**3))
            
            Ac(3) = Ac(3) - J3*(5.d0/2.d0)*(Gmr/r)*(q**3)*
     1                         (6.d0*(t**2)-7.d0*(t**4)-(3.d0/5.d0))
            
         end if
      
         if( NMAX .eq. 4 ) then
            
            PInm = dsqrt( 1.d0 / 9.d0 )
            J4 = -C(4,0)  / PInm
            
            Ac(1) = Ac(1) + J4*(15.d0/8.d0)*(Gmr/r)*(q**4)*
     1                      (X(1)/r)*(1.d0-14.d0*(t**2)+21.d0*(t**4))
            
            Ac(2) = Ac(2) + J4*(15.d0/8.d0)*(Gmr/r)*(q**4)*
     1                      (X(2)/r)*(1.d0-14.d0*(t**2)+21.d0*(t**4))
            
            Ac(3) = Ac(3) + J4*(15.d0/8.d0)*(Gmr/r)*(q**4)*
     1                 (X(3)/r)*(5.d0-70.d0*(t**2)/3.d0+21.d0*(t**4))
            
         end if
     
         return
          
      end if
      
C Summation initialization
C      Omega = 0.d0
      Vl = 0.d0
      Vf = 0.d0
      Vr = 0.d0

C Store sectoral
      pn(0) = 1.d0
      pn(1) = 1.7320508075688773D0 * u ! sqrt(3) * cos (lat)
      qn(0) = 1.d0
      qn(1) = q

      do m = 2, Nm
         am = dble(m)
         pn(m) = u * sqrt(1.d0+0.5d0/am) * pn(m-1)
         qn(m) = q * qn(m-1)
      end do

C       Initialize sin and cos recursions
      sm = 0.d0
      cm = 1.d0

C       Outer loop
      do  m = 0, Nm
      
C init 
         am = dble(m)

C For m = n 
         Pnm = pn(m)             ! m=n sectoral
         dPnm = -am * Pnm * tf
         Pnm1m = Pnm
         Pnm2m = 0.d0

C Init  Horner's scheme
         qC  = qn(m) * C(m,m)
         qS  = qn(m) * S(m,m)
         Xc  = qC * Pnm 
         Xs  = qS * Pnm
         Xcf = qC * dPnm 
         Xsf = qS * dPnm 
         Xcr = (am+1.d0) * qC * Pnm 
         Xsr = (am+1.d0) * qS * Pnm 

C Inner Loop 
         do   n = m+1, Nm
            an   = dble(n)
            anm  = sqrt( ((an+an-1.d0)*(an+an+1.d0))
     &               / ((an-am)*(an+am)) )
            bnm  = sqrt(  ((an+an+1.d0)*(an+am-1.d0)*(an-am-1.d0))
     &               / ((an-am)*(an+am)*(an+an-3.d0)) )
            fnm  = sqrt( ((an*an-am*am)*(an+an+1.d0))/(an+an-1.d0) )
C recursion P and dP
            Pnm  = anm *  t * Pnm1m - bnm * Pnm2m
            dPnm = -an * tf * Pnm   + fnm * Pnm1m / u   ! Signal opposite to paper

C Store
            Pnm2m = Pnm1m
            Pnm1m = Pnm

C Inner sum
            if (n .lt. 2) cycle
            
            qC = qn(n) * C(n,m)
            qS = qn(n) * S(n,m)
            Xc = (Xc + qC * Pnm)
            Xs = (Xs + qS * Pnm)
            Xcf = (Xcf + qC * dPnm)
            Xsf = (Xsf + qS * dPnm)
            Xcr = (Xcr + (an+1.d0) * qC * Pnm) 
            Xsr = (Xsr + (an+1.d0) * qS * Pnm) 
         end do

C Outer sum
C        Omega = Omega + (Xc*cm + Xs*sm)  
         Vl = Vl + am*(Xc *sm - Xs *cm) 
         Vf = Vf +    (Xcf*cm + Xsf*sm) 
         Vr = Vr +    (Xcr*cm + Xsr*sm)

C sin and cos recursions to next m
         cml = cl*cm - sm*sl
         sml = cl*sm + cm*sl
         cm = cml ! save to next m
         sm = sml ! save to next m

      end do

C Finalization, include n=0 (P00=1), 
C for n=1 all terms are zero: C,S(1,1), C,S(1,0) = 0

C Potential
C      Omega =  Gmr * (1.d0+Omega)

C Gradient 
      Vl = -Gmr * Vl
      Vf =  Gmr * Vf
      Vr = -(Gmr/r) * (1.d0+Vr)

C Body X, Y, Z accelerations 
      Ac(1) = u*cl*Vr - t*cl*Vf/r - sl*Vl/(u*r)
      Ac(2) = u*sl*Vr - t*sl*Vf/r + cl*Vl/(u*r)
      Ac(3) =    t*Vr +    u*Vf/r

      return
      end