macOS-এ src লেআউট ব্যবহার করে এমন একটি পাইথন প্রকল্পের জন্য প্যাকেজ ডিসকভারি কনফিগার করতে, pyproject.toml-এ setuptools-কে src-এর দিকে নির্দেশ করুন, তারপর প্যাকেজ-নাম ফিল্টার সেট করুন শুধুমাত্র যদি আপনার কোন প্যাকেজগুলো সরবরাহ করা হবে তা নিয়ন্ত্রণ করার প্রয়োজন হয়। একটি প্রচলিত প্রকল্পের জন্য, setuptools প্রায়শই লেআউটটি স্বয়ংক্রিয়ভাবে সনাক্ত করতে পারে; স্পষ্ট ডিসকভারি সেটিংস তখন কার্যকর হয় যখন আপনি পূর্বাভাসযোগ্য অন্তর্ভুক্তি বা বর্জন চান। এই নির্দেশাবলী setuptools-এর ক্ষেত্রে প্রযোজ্য, প্রতিটি পাইথন বিল্ড ব্যাকএন্ডের জন্য নয়।
প্রকল্পের কাঠামো এবং বিল্ড ব্যাকএন্ড পরীক্ষা করুন
টার্মিনাল থেকে, প্রকল্পের রুট ডিরেক্টরিতে যান—যে ফোল্ডারে pyproject.toml রয়েছে—এবং macOS-এর ডিফল্ট শেল, zsh, অথবা যদি আপনার কনফিগার করা শেল bash হয় তবে তা দিয়ে ফাইলগুলো পরিদর্শন করুন:
cd '/path/to/project'
find src -maxdepth 3 -type f -print
উদ্ধৃত পাথটিকে প্রকৃত প্রকল্পের অবস্থান দিয়ে প্রতিস্থাপন করুন। একক উদ্ধৃতি (Single quotes) পাথের স্পেস এবং শেল মেটাক্যারেক্টারগুলোকে ইন্টারপ্রেট হওয়া থেকে বিরত রাখে। একটি সাধারণ প্যাকেজ src/my_package/__init__.py-এ অবস্থিত হতে পারে, যার নিচের ডিরেক্টরিগুলোতে সাবপ্যাকেজ থাকে। ইমপোর্ট করার নামটি হলো my_package; src নামের ডিরেক্টরিটি কেবল একটি ধারক (container) এবং এটি সেই নামের অংশ নয়।
pyproject.toml-এ [build-system]-এর অধীনে setuptools নির্বাচিত আছে কিনা তা পরীক্ষা করুন, উদাহরণস্বরূপ requires = ["setuptools>=61"] এবং build-backend = "setuptools.build_meta" সহ। setuptools ডকুমেন্টেশনে সাধারণ লেআউটগুলোর (যার মধ্যে src-ও অন্তর্ভুক্ত) জন্য স্বয়ংক্রিয় ডিসকভারির বর্ণনা দেওয়া হয়েছে, যখন প্যাকেজ এবং মডিউল তালিকাগুলো স্পষ্টভাবে প্রদান করা হয় না। অন্যান্য ব্যাকএন্ডের নিজস্ব কনফিগারেশন রয়েছে, তাই setuptools-এর সেটিংস অন্য ব্যাকএন্ডের কনফিগারেশন টেবিলে কপি করবেন না। Setuptools: Configuring setuptools using pyproject.toml files
pyproject.toml-এ সুস্পষ্ট ডিসকভারি কনফিগার করুন
আপনি যদি ডিসকভারি বিশেষভাবে src-এর মূলে রাখতে চান, তবে বিদ্যমান ফাইলে নিম্নলিখিত setuptools কনফিগারেশনটি যোগ করুন:
[tool.setuptools.packages.find]
where = ["src"]
এটি setuptools-কে জানায় কোথায় প্যাকেজগুলো খুঁজতে হবে। এটি প্রকল্পের নাম বা প্যাকেজের ইমপোর্ট নাম পরিবর্তন করে না। আপনার যদি ইতিমধ্যে একটি [tool.setuptools.packages.find] টেবিল থাকে, তবে দ্বিতীয়টি যোগ করার পরিবর্তে সেই টেবিলটি সম্পাদনা করুন। TOML ফাইলে একই টেবিলের একাধিক বা ডুপ্লিকেট সংজ্ঞা থাকতে পারে না।
ডিসকভারিকে একটি একক প্যাকেজ এবং এর সাবপ্যাকেজগুলোতে সীমাবদ্ধ করতে, সম্পূর্ণ ডটেড প্যাকেজ নামের সাথে মিল রেখে একটি include প্যাটার্ন যোগ করুন:
[tool.setuptools.packages.find]
where = ["src"]
include = ["my_package*"]
my_package-কে প্রকৃত ইমপোর্ট প্যাকেজের নাম দিয়ে প্রতিস্থাপন করুন। * প্যাটার্নটিকে my_package.tools-এর মতো সাবপ্যাকেজগুলোর সাথে মিলতে সাহায্য করে; প্যাটার্নগুলো সম্পূর্ণ প্যাকেজের নামের সাথে মিলিয়ে দেখা হয়। আপনি নির্দিষ্ট প্যাকেজগুলোকে বাদও দিতে পারেন, উদাহরণস্বরূপ exclude = ["my_package.tests*"]। Setuptools তার প্যাকেজ ডিসকভারি নির্দেশিকায় এই include এবং exclude প্যাটার্নগুলোর পাশাপাশি where-এর বিবরণ দিয়েছে।
ডিসকভারি কীভাবে নেমস্পেস প্যাকেজগুলো পরিচালনা করবে তা নির্বাচন করুন
ডিফল্টভাবে, setuptools-এর pyproject.toml ডিসকভারি ইমপ্লিসিট নেমস্পেস প্যাকেজগুলো স্ক্যান করে: ডিরেক্টরিগুলোতে __init__.py না থাকলেও সেগুলোকে প্যাকেজ হিসেবে বিবেচনা করা যেতে পারে। আপনার প্যাকেজটি যদি ইচ্ছাকৃতভাবে PEP 420 নেমস্পেস প্যাকেজ ব্যবহার করে তবে এই ডিফল্টটি বজায় রাখুন। প্রতিটি প্যাকেজে যদি একটি করে __init__.py থাকা আবশ্যক হয়, তবে আপনি নেমস্পেস স্ক্যানিং বন্ধ করতে পারেন:
[tool.setuptools.packages.find]
where = ["src"]
namespaces = false
এই সেটিংটির ফলে, __init__.py ছাড়া ডিরেক্টরিগুলো প্যাকেজ হিসেবে সনাক্ত হবে না। সুতরাং বিল্ট ডিস্ট্রিবিউশনে কোনো প্যাকেজ অনুপস্থিত থাকার কারণ হতে পারে অনুসন্ধানের অবস্থান, কোনো include বা exclude প্যাটার্ন, অথবা নেমস্পেস সেটিং। প্যাকেজিং নির্দেশিকায় এই আচরণটি আলোচনা করা হয়েছে এবং ডিসকভারিকে কীভাবে নির্বাচিত নেমস্পেস প্যাকেজে সীমাবদ্ধ করা যায় তা দেখানো হয়েছে। Python Packaging User Guide: Packaging namespace packages
কখন স্বয়ংক্রিয় ডিসকভারিই যথেষ্ট তা জানুন
একটি সহজ-সরল src/my_package প্রকল্পের জন্য, আপনার সম্ভবত কোনো ডিসকভারি টেবিলেরই প্রয়োজন হবে না। packages এবং py-modules নির্দিষ্ট না করা থাকলে Setuptools সাধারণ লেআউটগুলো চিনতে পারে। যখন আপনার প্যাকেজ নির্বাচনকে সংকীর্ণ করার, কম প্রচলিত কোনো ট্রি পরিচালনা করার, বা সোর্স ডিরেক্টরিটিকে দ্ব্যর্থহীন করার প্রয়োজন হয়, তখন স্পষ্ট কনফিগারেশন যোগ করুন। প্যাকেজ ট্রি পরিবর্তনের সাথে সাথে সেগুলো বজায় রাখার ইচ্ছা না থাকলে আলাদাভাবে প্যাকেজ তালিকা হার্ড-কোড করা এড়িয়ে চলুন; স্পষ্ট তালিকার কারণে নতুন যোগ করা সাবপ্যাকেজগুলো সহজেই বাদ পড়ে যেতে পারে।
একটি src লেআউটের অর্থ এটিও যে রিপোজিটরি রুট থেকে পাইথন রান করলে প্যাকেজটি স্বয়ংক্রিয়ভাবে ইমপোর্ট পাথে চলে আসে না। এটি প্রত্যাশিত: setuptools-এর ডকুমেন্টেশনে উল্লেখ করা হয়েছে যে সোর্স চেকআউট থেকে এইভাবে প্যাকেজটি ব্যবহার করার জন্য একটি এডিটেবল ইনস্টলেশন (editable install) প্রয়োজন। ডিসকভারি কনফিগারেশন একটি ডিস্ট্রিবিউশনে কী অন্তর্ভুক্ত হবে তা নিয়ন্ত্রণ করে; এটি ডেভেলপমেন্টের জন্য আপনি যে পাইথন এনভায়রনমেন্ট ব্যবহার করেন তাতে প্রকল্পটি ইনস্টল করার বিকল্প নয়। Setuptools: Package Discovery and Namespace Packages
তথ্যসূত্র
Configuring setuptools using pyproject.toml files — setuptools
Package Discovery and Namespace Packages — setuptools
Packaging namespace packages — Python Packaging Authority