Skip to content

Commit f7bbb03

Browse files
committed
Documentation and readability
1 parent fe62a26 commit f7bbb03

4 files changed

Lines changed: 51 additions & 25 deletions

File tree

.github/workflows/main.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,9 @@ jobs:
8989
only: ${{ matrix.only }}
9090
env:
9191
CIBW_BUILD_VERBOSITY: 1
92+
# add compiled libmagic to the build directory (to include in the wheel)
9293
CIBW_BEFORE_BUILD: bash "add_libmagic.sh"
94+
# simple smoke test run on each wheel: this is an HLS MP4 video, only recognised in recent versions of libmagic
9395
CIBW_TEST_COMMAND: python -c "import magic; assert magic.Magic(mime=True).from_buffer(b'\x00\x00\x00\x1cftypiso5\x00\x00\x00\x01isomiso5hlsf\x00\x00') == 'video/mp4'"
9496

9597
- uses: actions/upload-artifact@v4

README.md

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
[![PyPI version](https://badge.fury.io/py/python-magic.svg)](https://badge.fury.io/py/python-magic)
33
[![Build Status](https://travis-ci.org/ahupp/python-magic.svg?branch=master)](https://travis-ci.org/ahupp/python-magic) [![Join the chat at https://gitter.im/ahupp/python-magic](https://badges.gitter.im/ahupp/python-magic.svg)](https://gitter.im/ahupp/python-magic?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
44

5-
python-magic is a Python interface to the libmagic file type
6-
identification library. libmagic identifies file types by checking
5+
[python-magic](https://github.com/ahupp/python-magic) is a Python interface to the libmagic file type
6+
identification library. libmagic identifies file types by checking
77
their headers according to a predefined list of file types. This
88
functionality is exposed to the command line by the Unix command
9-
`file`.
9+
[`file`](https://www.darwinsys.com/file/).
1010

1111
## Usage
1212

@@ -43,26 +43,25 @@ You can also combine the flag options:
4343

4444
## Installation
4545

46-
The current stable version of python-magic is available on PyPI and
47-
can be installed by running `pip install python-magic`.
46+
This module is a simple [CDLL](https://docs.python.org/3/library/ctypes.html) wrapper around the libmagic C library.
47+
The current stable version of python-magic is available on [PyPI](http://pypi.python.org/pypi/python-magic/)
48+
and can be installed by running `pip install python-magic`.
4849

49-
Other sources:
50+
Compiled libmagic and the magic database come bundled in the wheels on PyPI.
51+
You can use your own `magic.mgc` database by setting the `MAGIC`
52+
environment variable, or by using `magic.Magic(magic_file='path/to/magic.mgc')`.
53+
If you want to compile your own libmagic, circumvent the wheels
54+
by installing from source: `pip install python-magic --no-binary python-magic`.
5055

51-
- PyPI: http://pypi.python.org/pypi/python-magic/
52-
- GitHub: https://github.com/ahupp/python-magic
53-
54-
This module is a simple wrapper around the libmagic C library, and
55-
comes bundled in the wheels on PyPI.
56-
If you want to use your own (custom) libmagic installation,
57-
circumvent the wheels by running `pip install python-magic --no-binary python-magic`.
58-
For systems not supported by the wheels, libmagic
59-
needs to be installed before installing python-magic:
56+
For systems not supported by the wheels, pip installs from source,
57+
requiring libmagic to be available before installing python-magic:
6058

6159
### Linux
6260

6361
The Linux wheels should run on most systems out of the box.
6462

65-
Depending on your system and CPU architecture, there might be no compatible wheel uploaded. However, precompiled libmagic might still be available for your system:
63+
Depending on your system and CPU architecture, there might be no compatible wheel uploaded.
64+
However, precompiled libmagic might still be available for your system:
6665

6766
```sh
6867
# Debian/Ubuntu
@@ -75,13 +74,15 @@ yum install file-libs
7574

7675
### Windows
7776

78-
The DLLs that are bundled in the Windows wheels are compiled by @julian-r and hosted at https://github.com/julian-r/file-windows/releases.
77+
The DLLs that are bundled in the Windows wheels are compiled by @julian-r
78+
and are hosted at https://github.com/julian-r/file-windows/releases.
7979

8080
For ARM64 Windows, you'll need to compile libmagic from source.
8181

8282
### OSX
8383

84-
The Mac wheels are compiled on GitHub Actions using `macos-11` runners. For older Macs, you'll need to install libmagic from source:
84+
The Mac wheels are compiled with maximum backward compatibility.
85+
For older Macs, you'll need to install libmagic from source:
8586

8687
```sh
8788
# homebrew
@@ -95,7 +96,7 @@ port install file
9596
- 'MagicException: could not find any magic files!': some
9697
installations of libmagic do not correctly point to their magic
9798
database file. Try specifying the path to the file explicitly in the
98-
constructor: `magic.Magic(magic_file="path_to_magic_file")`.
99+
constructor: `magic.Magic(magic_file='path/to/magic.mgc')`.
99100

100101
- 'WindowsError: [Error 193] %1 is not a valid Win32 application':
101102
Attempting to run the 32-bit libmagic DLL in a 64-bit build of
@@ -105,7 +106,6 @@ port install file
105106
- 'WindowsError: exception: access violation writing 0x00000000 ' This may indicate you are mixing
106107
Windows Python and Cygwin Python. Make sure your libmagic and python builds are consistent.
107108

108-
109109
## Bug Reports
110110

111111
python-magic is a thin layer over the libmagic C library.

add_libmagic.sh

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
set -euxo pipefail
44

55
install_source() {
6+
# install from source
7+
# https://www.darwinsys.com/file/
8+
# https://github.com/file/file/blob/FILE5_45/INSTALL#L51
69
version="file-5.45"
710
(
811
tmpfile="$(mktemp)" &&
@@ -34,21 +37,33 @@ install_precompiled() {
3437
elif [ -n "$(which yum)" ]; then
3538
yum install file-libs
3639
else
37-
python -c 'import platform, sysconfig, io, zipfile, urllib.request; assert platform.system() == "Windows"; machine = "x86" if sysconfig.get_platform() == "win32" else "x64"; print(machine); zipfile.ZipFile(io.BytesIO(urllib.request.urlopen(f"https://github.com/julian-r/file-windows/releases/download/v5.44/file_5.44-build104-vs2022-{machine}.zip").read())).extractall(".")' &&
40+
# windows (no install, just download into current working directory)
41+
python <<EOF
42+
import platform, sysconfig, io, zipfile, urllib.request
43+
assert platform.system() == "Windows"
44+
machine = "x86" if sysconfig.get_platform() == "win32" else "x64"
45+
url = f"https://github.com/julian-r/file-windows/releases/download/v5.44/file_5.44-build104-vs2022-{machine}.zip"
46+
print("Downloading", url)
47+
zipfile.ZipFile(io.BytesIO(urllib.request.urlopen(url).read())).extractall(".")
48+
EOF
49+
# check what was copied
3850
ls -ltra
3951
fi
4052
}
4153

4254
copy_libmagic() {
4355
# on cibuildwheel, the lib needs to exist in the project before running setup.py
4456
# copy lib into the magic dir, regardless of platform
57+
# this python command relies on current working directory containing `./magic/loader.py`
4558
libmagic_path="$(python -c 'from magic.loader import load_lib; print(load_lib()._name)')" &&
4659
cp "${libmagic_path}" "magic" &&
47-
# only on linux: additionally copy compiled db into magic dir
60+
# only on linux: additionally copy compiled db into magic dir (prefer the one installed by install_source)
4861
( ( cp "/usr/local/share/misc/magic.mgc" "magic" || cp "/usr/share/misc/magic.mgc" "magic" ) || true ) &&
4962
# check what was copied
5063
ls -ltra magic
5164
}
5265

66+
# prefer a recent build from source
5367
install_source || install_precompiled
68+
# files to be copied into the wheel
5469
copy_libmagic

magic/loader.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@ def _lib_candidates():
1111
if sys.platform == 'darwin':
1212

1313
paths = [
14+
# libmagic bundled in the wheel
1415
here,
16+
# libmagic in the current working directory
1517
os.path.abspath('.'),
18+
# libmagic in other common sources like homebrew
1619
'/opt/local/lib',
1720
'/usr/local/lib',
1821
'/opt/homebrew/lib',
@@ -26,28 +29,34 @@ def _lib_candidates():
2629
prefixes = ['libmagic', 'magic1', 'magic-1', 'cygmagic-1', 'libmagic-1', 'msys-magic-1']
2730

2831
for i in prefixes:
29-
# find_library searches in %PATH% but not the current directory,
30-
# so look for both
32+
# libmagic bundled in the wheel
3133
yield os.path.join(here, '%s.dll' % i)
34+
# libmagic in the current working directory
3235
yield os.path.join(os.path.abspath('.'), '%s.dll' % i)
36+
# find_library searches in %PATH% but not the current directory
3337
yield find_library(i)
3438

3539
elif sys.platform == 'linux':
3640

3741
prefixes = ['libmagic.so.1', 'libmagic.so']
3842

3943
for i in prefixes:
44+
# libmagic bundled in the wheel
4045
yield os.path.join(here, i)
46+
# libmagic in the current working directory
4147
yield os.path.join(os.path.abspath('.'), i)
48+
# libmagic install from source default destination path
4249
yield os.path.join('/usr/local/lib', i)
4350
# on some linux systems (musl/alpine), find_library('magic') returns None
44-
# first try ldconfig with backup string in case of error
51+
# first try finding libmagic using ldconfig
52+
# otherwise fall back to /usr/lib/
4553
yield subprocess.check_output(
4654
"( ldconfig -p | grep '{0}' | grep -o '/.*' ) || echo '/usr/lib/{0}'".format(i),
4755
shell=True,
4856
universal_newlines=True,
4957
).strip()
5058

59+
# fallback
5160
yield find_library('magic')
5261

5362

0 commit comments

Comments
 (0)