Làm cách nào để tìm vị trí của thư mục gói trang Python của tôi?


942

Làm cách nào để tìm vị trí của thư mục gói trang web của tôi?


63
Nếu bạn chỉ muốn vị trí chính xác của một gói thì bạn có thể sử dụngpip show <package name>
joshuakcockrell

Câu trả lời:


532

Có hai loại thư mục gói trang web, toàn cầumỗi người dùng .

  1. Các thư mục gói toàn cầu (" dist-gói ") được liệt kê sys.pathkhi bạn chạy:

    python -m site

    Để có danh sách ngắn gọn hơn chạy getsitepackagestừ mô-đun trang web trong mã Python:

    python -c 'import site; print(site.getsitepackages())'

    Lưu ý: Tuy nhiên, với các phần mềm ảoenvs không có sẵn , sys.pathtừ trên sẽ liệt kê chính xác thư mục gói trang web của virtualenv. Trong Python 3, bạn có thể sử dụng mô-đun sysconfig thay thế:

    python3 -c 'import sysconfig; print(sysconfig.get_paths()["purelib"])'
  2. Thư mục gói trang web trên mỗi người dùng ( PEP 370 ) là nơi Python cài đặt các gói cục bộ của bạn:

    python -m site --user-site

    Nếu điều này trỏ đến một thư mục không tồn tại, hãy kiểm tra trạng thái thoát của Python và xem python -m site --helpgiải thích.

    Gợi ý: Chạy pip list --userhoặc pip freeze --usercung cấp cho bạn danh sách tất cả các gói trang web được cài đặt cho mỗi người dùng .


Những mẹo có ích

  • <package>.__path__cho phép bạn xác định (các) vị trí của gói cụ thể: ( chi tiết )

    $ python -c "import setuptools as _; print(_.__path__)"
    ['/usr/lib/python2.7/dist-packages/setuptools']
  • <module>.__file__cho phép bạn xác định vị trí của một mô-đun cụ thể: ( sự khác biệt )

    $ python3 -c "import os as _; print(_.__file__)"
    /usr/lib/python3.6/os.py
  • Chạy pip show <package>để hiển thị thông tin gói kiểu Debian:

    $ pip show pytest
    Name: pytest
    Version: 3.8.2
    Summary: pytest: simple powerful testing with Python
    Home-page: https://docs.pytest.org/en/latest/
    Author: Holger Krekel, Bruno Oliveira, Ronny Pfannschmidt, Floris Bruynooghe, Brianna Laugher, Florian Bruhin and others
    Author-email: None
    License: MIT license
    Location: /home/peter/.local/lib/python3.4/site-packages
    Requires: more-itertools, atomicwrites, setuptools, attrs, pathlib2, six, py, pluggy

17
có một thư mục gói trang web trong virtualenv. Bạn có thể lấy thư mục cho các mô-đun dành riêng cho trang web bên trong / bên ngoài virtualenv bằng cách sử dụng python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"(nó cũng hoạt động trên cả Python 2 và 3).
jfs

4
Đẹp. Và để có được cái đầu tiên:python -c "import site; print(site.getsitepackages()[0])"
Brent Faust

2
Điều này nên có trong bất kỳ hướng dẫn cơ bản về việc sử dụng python. Tôi đã trăn trối trong nhiều năm và không biết gì về mô-đun trang web. Sẽ cứu được rất nhiều người đau đầu ...
salotz

1
Tôi đã đề nghị thay đổi hướng dẫn chính thức của Python. Vui lòng xem PR # 16974 để biết chi tiết và cảm ơn về gợi ý @salotz!
Peterino

1
Tôi nghĩ stackoverflow.com/a/52638888/1365918 dễ dàng là câu trả lời tốt nhất cho câu hỏi này.
kapad

652
>>> import site; site.getsitepackages()
['/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages']

(hoặc chỉ mục đầu tiên với site.getsitepackages()[0])


17
Điều này là tốt nhưng thật không may, chức năng này chỉ có sẵn từ python2.7. Vì vậy, giải pháp tốt nếu bạn đang sử dụng python2.7 trở lên, nhưng không hoạt động cho python 2.6 trở xuống
Dan Niero

15
python -c "trang web nhập khẩu; in (site.getsitepackages ())"
Lars Schneider

29
Tôi nhận được AttributionError: đối tượng 'mô-đun' không có thuộc tính 'getitepackages' khi sử dụng với virtualenv (python 2.7.8), giải pháp distutils bên dưới hoạt động.
radtek

8
@radtek: đối với venv's, tôi phát hiện venv qua hasattr(sys,'real_prefix')và sau đó xác định các gói trang web theo phương pháp heuristur [p for p in sys.path if p.endswith('site-packages')][-1](cộng với kiểm tra nếu có một cái được tìm thấy trước khi thực hiện [-1].
eudoxos

4
@radtek Một lỗi được biết là mô-đun trang web không hoạt động cho virtualenv github.com/pypa/virtualenv/issues/355
Guillem Cucurull

319

Một giải pháp:

  • bên ngoài virtualenv - cung cấp đường dẫn của các gói trang web toàn cầu ,
  • bảo vệ một virtualenv - cung cấp các gói trang web của virtualenv

... Đây là một lớp lót:

python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"

Được định dạng để dễ đọc (thay vì sử dụng như một lớp lót), trông giống như sau:

from distutils.sysconfig import get_python_lib
print(get_python_lib())


Nguồn: một phiên bản rất cũ của tài liệu "Cách cài đặt Django" (mặc dù điều này hữu ích với nhiều thứ hơn là chỉ cài đặt Django)


1
Virtualenv có cung cấp cách tìm gói trang web không?
Daryl Spitzer

10
Bạn có thể sử dụng virtualenvwrapper, có lệnh cdsitepackages, để trực tiếp thay đổi vào thư mục gói trang web của môi trường.
john2x

6
@PiotrDobrogost: hoạt động với tôi trên Python 2.7 trong một virtualenv trên Linux
RichVel

2
Nhận xét đầu tiên không áp dụng nữa: điều này cho thấy vị trí chính xác cả bên ngoài và bên trong một virtualenv.
astrojuanlu

2
Không hoạt động với tôi trên Windows 10 bằng Linux bash, nó trả về /usr/lib/python3/dist-packagesthay vì /usr/lib/python3.5/dist-packages.
Delgan

99

Đối với Ubuntu ,

python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"

... không đúng

Nó sẽ chỉ cho bạn /usr/lib/pythonX.X/dist-packages

Thư mục này chỉ chứa các gói mà hệ điều hành của bạn đã tự động cài đặt để các chương trình chạy.

Trên Ubuntu , thư mục gói trang web chứa các gói được cài đặt qua setup_tools \ easy_install \ pip sẽ nằm trong/usr/local/lib/pythonX.X/dist-packages

Thư mục thứ hai có lẽ là thư mục hữu ích hơn nếu trường hợp sử dụng có liên quan đến cài đặt hoặc đọc mã nguồn.

Nếu bạn không sử dụng Ubuntu, có lẽ bạn đã sao chép an toàn hộp mã đầu tiên vào thiết bị đầu cuối.


3
Nếu người hỏi ở sau vị trí của một gói cụ thể, thì đó module.__file__là cách tốt hơn. Nếu họ đang cố gắng cài đặt mọi thứ, hãy sử dụng các công cụ.
Tobu

'/usr/lib/pythonX.X/dist-packages' in site.getsitepackages()trên Ubuntu (mặc dù nó đi sau /usr/local/... trong danh sách). Bạn chỉ nhận được một cái gì đó /usr/localthông qua sudo pipvà bạn không nên sử dụng sudo piptrên Ubuntu trừ khi bạn quyết định tự phân phối: nếu bạn sử dụng sudo pip, bạn có trách nhiệm đảm bảo rằng tất cả các phụ thuộc của các mô-đun python hiện tại và tương lai được cài đặt thông qua sudo apthoặc sudo piptương thích. Xem xét vấn đề nào virtualenvđược tạo ra để giải quyết
jfs

Giải thích rõ ràng để hiểu sự khác biệt của dist-packagesUbuntu 2 trong (L).
Timo

69

Đây là những gì làm việc cho tôi:

python -m site --user-site

15
Đối với tôi điều này chỉ đến một thư mục thậm chí không tồn tại ( ~/.local/lib/python2.7/site-packages).
Neil Traft

1
tương tự, trong OS X Mavericks, nhà của tôi. không phải là thứ tôi muốn nó tìm thấy cộng với nó không thực sự ở đó.
radtek

Trong thư mục chính / Thư viện của tôi, tôi phải điều hướng thủ công đến nó, vì một số lý do, đường dẫn đầy đủ trực tiếp không hoạt động
efwjames

Làm thế nào để tôi sử dụng các gói được cài đặt ở đây? nếu tôi làm điều virtualenvđó phàn nàn rằng gói không tồn tại. Làm thế nào để tôi gọi các gói được cài đặt tại một vị trí tùy chỉnh?
AbtPst

2
Điều này cho bạn biết Python sẽ tìm kiếm các gói cụ thể của người dùng ở đâu. Những bình luận như "thậm chí không tồn tại" và "không phải là thứ tôi muốn nó tìm thấy" không có ý nghĩa trong bối cảnh này.
thật Abe

28

Giả sử bạn đã cài đặt gói 'django'. nhập nó và gõ vào dir (django). Nó sẽ cho bạn thấy, tất cả các chức năng và thuộc tính với mô-đun đó. Nhập trình thông dịch python -

>>> import django
>>> dir(django)
['VERSION', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', 'get_version']
>>> print django.__path__
['/Library/Python/2.6/site-packages/django']

Bạn có thể làm điều tương tự nếu bạn đã cài đặt đồng bóng.

Đây là cho báo tuyết. Nhưng tôi nghĩ rằng nó nên làm việc nói chung là tốt.


>>> nhập pg >>> in pg .__ path__ TracBack (cuộc gọi gần đây nhất): Tệp "<stdin>", dòng 1, trong <module> AttributionError: 'module' object không có thuộc tính ' path '
Dannid

nó hoạt động, tôi cần tìm gói sklearn để thêm vào đường dẫn PYDEV, cảm ơn.
berkay

sử dụng django.__file__cho việc này hơn là __path__. và, không, không đảm bảo rằng điều này có liên quan đến các gói trang web, nhưng với những thứ như django, rất có thể bạn đã cài đặt pip , nó sẽ hoạt động khi bạn đang vội và có thể sử dụng nó cho các mục đích khác cũng vậy (ví dụ đọc tệp cấu hình mặc định từ hệ thống tệp).
JL Peyret

Dựa trên câu trả lời này và các câu trả lời khác, bạn có thể thực hiện điều này trong một dòng từ dòng lệnh để có được đường dẫn đến foo.bargói của bạn :python -c "import foo.bar as _; print(_.__path__[0])"
snark

23

Như những người khác đã lưu ý, distutils.sysconfigcó các cài đặt liên quan:

import distutils.sysconfig
print distutils.sysconfig.get_python_lib()

... mặc dù mặc định site.pylàm một cái gì đó thô thiển hơn một chút, được diễn giải dưới đây:

import sys, os
print os.sep.join([sys.prefix, 'lib', 'python' + sys.version[:3], 'site-packages'])

(nó cũng thêm ${sys.prefix}/lib/site-pythonvà thêm cả hai đường dẫn sys.exec_prefix, nếu hằng số đó khác nhau).

Điều đó nói rằng, bối cảnh là gì? Bạn không nên nhắn tin site-packagestrực tiếp với bạn ; setuptools / distutils sẽ hoạt động để cài đặt và chương trình của bạn có thể đang chạy trong virtualenv nơi pythonpath của bạn hoàn toàn do người dùng cục bộ, do đó, không nên sử dụng trực tiếp các gói trang web của hệ thống.


3
hoạt động đáng tin cậy với python2trên osx và ubfox có và không có virtualenv nhưng hoàn toàn không python3.
jitter

2
Năm 2008 đã quay trở lại - câu trả lời này là ba tháng trước khi phát hành Python 3.0.
Charles Duffy

chắc chắn, nhưng hôm nay nhận xét của tôi có thể giúp đỡ. sửa tôi nếu tôi sai hơn nữa, tôi đã không đánh giá thấp câu trả lời này hoặc bất kỳ câu hỏi nào khác liên quan đến python3.
jitter

22

Một cách stdlib hiện đại là sử dụng sysconfigmô-đun, có sẵn trong phiên bản 2.7 và 3.2+.

Lưu ý : sysconfig( nguồn ) không được nhầm lẫn với distutils.sysconfigmô hình con ( nguồn ) được đề cập trong một số câu trả lời khác ở đây. Cái sau là một mô-đun hoàn toàn khác và nó thiếu get_pathschức năng được thảo luận dưới đây.

Python hiện sử dụng tám đường dẫn ( docs ):

  • stdlib : thư mục chứa các tệp thư viện Python tiêu chuẩn không dành riêng cho nền tảng.
  • platstdlib : thư mục chứa các tệp thư viện Python tiêu chuẩn dành riêng cho nền tảng.
  • platlib : thư mục cho các tệp cụ thể theo trang web, nền tảng cụ thể.
  • purelib : thư mục dành cho các tệp dành riêng cho trang web, không dành riêng cho nền tảng.
  • bao gồm : thư mục cho các tệp tiêu đề không dành riêng cho nền tảng.
  • platinclude : thư mục cho các tệp tiêu đề dành riêng cho nền tảng.
  • scripts : thư mục cho tập tin script.
  • data : thư mục cho các tập tin dữ liệu.

Trong hầu hết các trường hợp, người dùng tìm thấy câu hỏi này sẽ quan tâm đến đường dẫn 'purelib' (trong một số trường hợp , bạn cũng có thể quan tâm đến 'platlib'). Không giống như câu trả lời được chấp nhận hiện tại, phương pháp này vẫn hoạt động bất kể bạn có kích hoạt virtualenv hay không.

Ở cấp độ hệ thống (đây là Python 3.7.0 trên hệ điều hành mac):

>>> import sysconfig
>>> sysconfig.get_paths()['purelib']
'/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages'

Với một venv, bạn sẽ nhận được một cái gì đó như thế này

>>> import sysconfig
>>> sysconfig.get_paths()['purelib']
'/private/tmp/.venv/lib/python3.7/site-packages'

Một kịch bản shell cũng có sẵn để hiển thị các chi tiết này, mà bạn có thể gọi bằng cách thực hiện sysconfigdưới dạng một mô-đun:

python -m sysconfig

Đây là một câu trả lời tuyệt vời, tôi rất vui khi mô-đun sysconfig mới làm cho việc này dễ dàng hơn. Có cách nào để có được tiền tố cục bộ platlib, ví dụ như /usr/local/lib/python3.6/site-packageskhông? Theo truyền thống, những thứ được cài đặt cục bộ nên đi vào /usr/local.
eudoxos

Dễ dàng trả lời tốt nhất cho câu hỏi này! Cảm ơn bạn. Điều duy nhất tôi thấy thiếu là thứ tự kiểm tra các vị trí này khi gặp phải một câu lệnh nhập khẩu. Ngoài ra, có bất kỳ vị trí nào trong số những vị trí này được tìm kiếm trước / lưu vào bộ đệm khi python được tải không? Biết rằng cũng sẽ hữu ích IMO.
kapad

21

Có thể tìm thấy các gói hệ thống gốc được cài đặt với cài đặt python trong các hệ thống dựa trên Debian tại:

/usr/lib/python2.7/dist-packages/

Trong OSX - /Library/Python/2.7/site-packages

bằng cách sử dụng mã nhỏ này:

from distutils.sysconfig import get_python_lib
print get_python_lib()

Tuy nhiên, danh sách các gói được cài đặt qua pipcó thể được tìm thấy tại:

/ usr / địa phương / bin /

Hoặc người ta có thể chỉ cần viết lệnh sau để liệt kê tất cả các đường dẫn có các gói python.

>>> import site; site.getsitepackages()
['/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages']

Lưu ý: vị trí có thể thay đổi dựa trên HĐH của bạn, như trong OSX

>>> import site; site.getsitepackages()
['/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages', '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/site-python', '/Library/Python/2.7/site-packages']

Nếu tôi nhớ chính xác, các gói dist dành riêng cho Debian và các dẫn xuất.
Samuel

1
@SamuelSantana bạn đúng. gói dist là cụ thể cho các hệ thống dựa trên debian. Trong trường hợp này, tôi đã gọi site.getsitepackages()từ cài đặt hệ thống do đó các gói dist, các cài đặt khác sẽ hiển thị các gói trang web.
fnatic_shank 23/03/18

15

Tất cả các câu trả lời (hoặc: cùng một câu trả lời lặp đi lặp lại) là không đầy đủ. Những gì bạn muốn làm là đây:

from setuptools.command.easy_install import easy_install
class easy_install_default(easy_install):
  """ class easy_install had problems with the fist parameter not being
      an instance of Distribution, even though it was. This is due to
      some import-related mess.
      """

  def __init__(self):
    from distutils.dist import Distribution
    dist = Distribution()
    self.distribution = dist
    self.initialize_options()
    self._dry_run = None
    self.verbose = dist.verbose
    self.force = None
    self.help = 0
    self.finalized = 0

e = easy_install_default()
import distutils.errors
try:
  e.finalize_options()
except distutils.errors.DistutilsError:
  pass

print e.install_dir

Dòng cuối cùng cho bạn thấy các dir cài đặt. Hoạt động trên Ubuntu, trong khi những cái trên thì không. Đừng hỏi tôi về windows hoặc các dists khác, nhưng vì nó chính xác là cùng một dir mà easy_install sử dụng theo mặc định, nên nó có thể chính xác ở mọi nơi mà easy_install hoạt động (vì vậy, ở mọi nơi, thậm chí cả mac). Chúc vui vẻ. Lưu ý: mã gốc có nhiều từ ngữ trong đó.


1
Cảm ơn, điều này khá hữu ích, trên py3 có dấu ngoặc để in, nó giúp tôi /usr/local/lib/python3.4/dist-packages Tôi đang cố gắng tìm cách lấy /usr/lib/python3.4/dist -packages vì ​​vậy sẽ phải chơi xa hơn.
Stuart Axon

4
yêu cầu thư viện bên ngoài easy_installvà không thất bại một cách duyên dáng nếu không có sẵn mà không đủ :)
jitter

1
thật vậy, điều này không hoàn hảo, nhưng nó hiệu quả với tôi và mất rất nhiều thời gian để tìm ra, vì vậy tôi đặt nó ở đây với hy vọng người khác có thể xây dựng theo thời gian tôi đã dành cho nó.
kẻ lừa đảo

13

Lưu ý phụ: Giải pháp được đề xuất ( distutils.sysconfig.get_python_lib()) không hoạt động khi có nhiều hơn một thư mục gói trang web (theo khuyến nghị của bài viết này ). Nó sẽ chỉ trả về thư mục gói trang web chính.

Than ôi, tôi cũng không có giải pháp nào tốt hơn. Python dường như không theo dõi các thư mục gói trang web, chỉ các gói trong chúng.


1
Tôi đoán đó là lý do tại sao get_python_lib()khi được chạy từ trong virtualenv hiển thị các gói trang web của Python được sử dụng để tạo virtualenv chứ không phải các gói trang web của virtualenv .
Piotr Dobrogost

3
@Piotr Đó có lẽ là một lỗi trong distutils.sysconfig. Tôi vừa mới thử nó, tôi nhận được các gói trang web bên trong, như mong đợi.
Tobu

Cũng đã thử nghiệm với Python 2.7 được cài đặt trong virtualenv trên Linux và phương thức distutils.sysconfig hoạt động tốt để có được các gói trang web của Python bên trong.
RichVel

12

Điều này làm việc cho tôi. Nó sẽ giúp bạn có cả thư mục gói và gói trang web. Nếu thư mục không nằm trên đường dẫn của Python, dù sao nó cũng sẽ không giúp bạn nhiều.

import sys; 
print [f for f in sys.path if f.endswith('packages')]

Đầu ra (cài đặt Ubuntu):

['/home/username/.local/lib/python2.7/site-packages',
 '/usr/local/lib/python2.7/dist-packages',
 '/usr/lib/python2.7/dist-packages']

2
câu trả lời được chấp nhận là cách được đề xuất, vì vậy bạn nên cho biết lý do tại sao câu trả lời của bạn tốt hơn, vì đó là một chút hack
CharlesB

Có gì sai với hack? ;) Nó đơn giản và dễ hiểu và dễ nhớ hơn nếu bạn làm việc tương tác.
just_an_old_guy

11

Điều này sẽ hoạt động trên tất cả các bản phân phối trong và ngoài môi trường ảo do tính chất "công nghệ thấp" của nó. Mô-đun os luôn nằm trong thư mục mẹ của 'gói trang web'

import os; print(os.path.dirname(os.__file__) + '/site-packages')

Để thay đổi thư mục thành thư mục gói trang web, tôi sử dụng bí danh sau (trên các hệ thống * nix):

alias cdsp='cd $(python -c "import os; print(os.path.dirname(os.__file__))"); cd site-packages'

10

Một lưu ý bổ sung cho get_python_libchức năng đã được đề cập: trên một số nền tảng, các thư mục khác nhau được sử dụng cho các mô-đun cụ thể của nền tảng (ví dụ: các mô-đun yêu cầu biên dịch). Nếu bạn chuyển plat_specific=Trueđến chức năng, bạn sẽ nhận được các gói trang web cho các gói cụ thể của nền tảng.


8
from distutils.sysconfig import get_python_lib
print get_python_lib()


3

Trả lời câu hỏi cũ. Nhưng sử dụng ipython cho việc này.

pip install ipython
ipython 
import imaplib
imaplib?

Điều này sẽ cung cấp đầu ra sau đây về gói imaplib -

Type:        module
String form: <module 'imaplib' from '/usr/lib/python2.7/imaplib.py'>
File:        /usr/lib/python2.7/imaplib.py
Docstring:  
IMAP4 client.

Based on RFC 2060.

Public class:           IMAP4
Public variable:        Debug
Public functions:       Internaldate2tuple
                        Int2AP
                        ParseFlags
                        Time2Internaldate

1
Đây không phải là thư mục gói trang web, mà là thư mục mà gói được cài đặt vào. Điều này cũng chỉ hữu ích nếu bạn đang sử dụng iPython và không có khả năng lập trình để có được một thư mục cài đặt.
danielunderwood

3

Bạn nên thử lệnh này để xác định vị trí cài đặt của pip

Con trăn 2

pip show six | grep "Location:" | cut -d " " -f2

Con trăn 3

pip3 show six | grep "Location:" | cut -d " " -f2

1

Tôi đã phải làm một cái gì đó hơi khác nhau cho một dự án tôi đang làm việc trên: tìm ra tương đối trang web gói thư mục liên quan đến các cơ sở cài đặt tiền tố. Nếu thư mục gói trang web nằm trong /usr/lib/python2.7/site-packages, tôi muốn có /lib/python2.7/site-packagesmột phần. Trên thực tế, tôi đã gặp phải các hệ thống site-packagesđang ở trong đó /usr/lib64và câu trả lời được chấp nhận KHÔNG hoạt động trên các hệ thống đó.

Tương tự như câu trả lời của kẻ lừa đảo, giải pháp của tôi nhìn sâu vào ruột của Distutils, để tìm ra con đường thực sự được truyền qua bên trong setup.py. Thật là một nỗi đau khi tôi không muốn bất cứ ai phải tìm hiểu điều này một lần nữa.

import sys
import os
from distutils.command.install import INSTALL_SCHEMES

if os.name == 'nt':
    scheme_key = 'nt'
else:
    scheme_key = 'unix_prefix'

print(INSTALL_SCHEMES[scheme_key]['purelib'].replace('$py_version_short', (str.split(sys.version))[0][0:3]).replace('$base', ''))

Điều đó sẽ in một cái gì đó như /Lib/site-packageshoặc /lib/python3.6/site-packages.


-2

Nếu nó đã được thêm vào, PYTHONPATHbạn cũng có thể làm một cái gì đó như

import sys
print('\n'.join(sys.path))
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.