Skip to main content

A brute-force shortcut to fix python import hell. Acronym, standing for, um, Fix Up Python Imports. Sure, let's go with that.

Project description

fupi

A brute-force shortcut to fix python import hell. Acronym standing for... um, Fixing-Up Python Imports. Sure, let's go with that.

Usage

Simply import fupi in your project:

import fupi

This automatically detects and adds relevant directories (src, test, app) and their children to your sys.path, making imports work seamlessly across your project structure regardless of how bad you screw it up. This allow you to run components independently, run tests from anywhere, etc.

This can be a bit dangerous in larger projects with potentially duplicate namespaces, as you'd have no idea what you're actually importing unless you're explicit. You can create a local fupi.env file to limit the scope of what it auto-adds to sys.path, which will help. This is a "move fast and break things" type of project; you have been warned.

Also, you may consider commenting out import fupi once you get deployment and testing automated / located to a centralized starting point, again to make sure you're not hiding import bugs - by that point you won't likely need this brute-force tool. Fupi is really good at speeding up rapid-deploy tests / POCs / etc. by allowing you to import from anywhere in your project, starting from anywhere else in your project - aka coding fast and loose. This is most useful for one-person projects (of which AI is increasing the number and velocity).

Configuration

No configuration is needed if you use the defaults:

  • Adds src, test, app folders and subfolders to sys.path...
  • Skipping most common non-application file folders, like .git, venv*, __pycache__, setup, etc.

.ENV File Config

To use different / more folder names, simply add the following to an existing .env file, or create a new *.env or fupi.env file:

FUPI_ADD_DIRS="src,test"
FUPI_SKIP_DIRS="setup,venv*,*egg*"

The program will evaluate every *.env file it finds in the current working directory, it's parent, and all it's children. It then picks the best one that contains the two envars above. Those envars have slightly different behaviors:

The FUPI_ADD_DIRS will be string-matched against folders in your project, and on exact match, will include that folder and all subfolders into your sys.path.

The FUPI_SKIP_DIRS is a collection of regex patterns to skip, with string begin and end tags added (^value$). Thus you can simply add a list of folder names, or use basic wildcard * characters. If you want to get crazy with regex, be my guest - but understand the value will be wrapped (^value$).

The FUPI_SKIP_DIRS will also always append patterns to disqualify any path starting with a period('.') or an underscore('_') (i.e., '\.*' and '\_*'), which should catch most common skipped folders like .git, __pycache__, etc.

Environment Variable Config

Alternatively, you can add the above to os.envars BEFORE you import fupi. Similar to the .env approach above, simply add a comma-delimited list of all folder names / regex patterns.

Note, this process does NOT use dotenv, as it would auto-load ALL contents of .env files into os.envars, which could lead to unpredictable behavior. The process is very similar, but restricted to only FUPI_* variables.

Manual Setting

You can also manually call the functions in the fupi libary with whatever settings you'd like. To take advantage of this option, you'll have to escape the default behavior to auto-load to sys.path on import fupi. To escape the auto-run, add a single .env or envvar as per below:

FUPI_ADD_DIRS="disable"

Then you can configure manually, with:

from fupi import fupi
fupi.add_dirs_and_children_to_syspath(
    add_dirs=['my','app','folders'], 
    skip_dirs=['not','*these*'])

Alternatively, you can allow the auto-load, then reset the sys.path using the roll-back ability, below.

Rollback

If you want to roll-back to a previous state, sys.path contents are logged in the object sys_path_history which captures the pre-import snapshot at index[0], and subsequent snapshots every time a change is made. This would allow you to 'roll-back' to a pre-exexution state by simply:

sys.path = fupi.sys_path_history['history'][0]

Linters and AI Coders

The auto-load feature was designed to get down to two words for most use-cases: import fupi - nothing else is needed. One minor disadvantage; linters will often see this as an unused import, and flag it for removal, and/or give you a yellow squiggly underline. Or, an overly-ambitious AI coding tool may drop it without warning. If either bothers you, use the Manual Settings approach, or um, logger.info( fupi.sys_path_history ) for posterity's sake? Couldn't hurt. If it gets to be a real problem, I can add fupi.do_really_important_things() that does nothing. Let AI figure that out.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fupi-1.21.tar.gz (10.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fupi-1.21-py3-none-any.whl (8.2 kB view details)

Uploaded Python 3

File details

Details for the file fupi-1.21.tar.gz.

File metadata

  • Download URL: fupi-1.21.tar.gz
  • Upload date:
  • Size: 10.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.5

File hashes

Hashes for fupi-1.21.tar.gz
Algorithm Hash digest
SHA256 1135dddf3d578ffe5857b51cd16f44b8b16d31d00e3c0ceb5a968befcb9baedc
MD5 855756f8b17f6691c8804ca3f002ffd0
BLAKE2b-256 8123b2afc32a6a66cfaa99b6cbbc2fb9e1a10265d390ac230c12e1c718076763

See more details on using hashes here.

File details

Details for the file fupi-1.21-py3-none-any.whl.

File metadata

  • Download URL: fupi-1.21-py3-none-any.whl
  • Upload date:
  • Size: 8.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.5

File hashes

Hashes for fupi-1.21-py3-none-any.whl
Algorithm Hash digest
SHA256 cd4a97c6160ce57d7df4bc5dcf2004a6796b4b01f87095bd3440a9f65a5c4cfa
MD5 5b72873c0c5db79673cb48db110e4add
BLAKE2b-256 3cc2c21d0b8cdd388db5cbcb56cce7f3a15dc02e397e94f0b3f4ce4538786e95

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page