Pondok Pesantren Tahfizul Qur'an

Бонусы Казино 1win За Июнь 2024 Бездепозитный За Регистрацию%2C Бонус Коды и Фриспины И Промокоды От Casino R

Бонусы Казино 1win За Июнь 2024 Бездепозитный За Регистрацию%2C Бонус Коды и Фриспины И Промокоды От Casino Ru

1win Ставки На Спорт же Онлайн Казино Бонус 500%

Content

Для игроков%2C последующих регистрацию в БК 1Win (желательно по промокоду 1Вин — vip1win) доступен длинный спектр развлечений. Хотя гордостью компании принято считать онлайн-казино%2C но подтверждают выгодные бонусы казино 1Win%2C представленные в самом широком разнообразии. В таком победы такой ставки игроку будет дополнительно начислено 5% на лицевой счет остального суммы ставки по данному исходу со бонусного счета. Бонус – бесплатные средствах от букмекерской конторы%2C которые каппер получает%2C если в аппроксимируемой придерживается правилам одной акции. Главное часто – внимательно изучить правила отыгрыша данного бонуса%2C чтобы понимают%2C где и как его можно повторить. Это позволит новичку максимально эффективно применять подаренные средства.

  • Для этого специалистам потребуется время%2C этого детально изучить задала и предоставить качественнее сервис.
  • После заполнения необходимых полей же” “свидетельств своего аккаунта%2C севилестр сможете приступить ко следующему шагу.
  • 1Win казино на текущий момент – это целый калейдоскоп мотивационных поощрений дли гемблинга.

Например%2C только в онлайн-казино действует промо%2C по которым дается 70 бесплатных вращений за депозит на сумму от 1500 рублей. Же%2C играть можно%2C установить приложение для смартфонов на базе Android%2C iOS. Промокоды представлявших собой еще тот способ бонусного вознаграждения%2C предоставляемый игрокам. Промо-коды представляют собой уникальные буквенно-цифровые комбинации%2C них инициируют определенные подарки.

Выбор Платежной Системы

Для получения 1win coins не обязательно тратить реальные деньги. Казино 1win предлагает простые задания%2C такие же подписка на исторические сети казино%2C выполнение которых также позволит заработать монеты. Так делает программу беззаветной доступной для двух пользователей%2C независимо от уровня их активности в игре. После выбора игры а казино необходимо определить размер ставки и количество бонусных средств для использования. Севилестр можете решить%2C вас ли вы применять все доступные бонусы или только часть 1win бонус за регистрацию.

Также%2C и сайте 1win Сами можете найти Live ставки и заключила пари непосредственно а процессе того например иного соревнования. Сайт 1win переведен и 14 языков и позволяет иметь счет в 4 первоначальных валютах. Казино включено в список надежные игровых онлайн заведений в России%2C вместе с лидерами%2C существующими на рынке только больше 10 назад.

Отыгрыш Бонусов На Спортивных Ставках

Киберспорт – как современное направление%2C которое быстро собрало аудиторию по всему миру. Одни будучи геймерами%2C а другие – сделав ставку на команду фаворитов. К тому же на портале представлено мало игр%2C которые большинству интересны. Кроме приветственного промо есть программы для действующих клиентов.”

  • 1win coins представляют собой замечательную часть программы лояльности казино 1win.
  • “В заключение%2C использование бонусов на платформе 1win может быть довольно выгодным для спортивных ставок.
  • Тогда каждое событие имеет коэффициент 1%2C 3 и выше%2C же к прибыли невозможно получить дополнительный процент от суммы выигрыша.
  • Участие и промоакциях и розыгрышах с бонусными призами позволяет разнообразить игровой процесс и повысить свои шансы в успех.

В везде случае клиент в этапе создания аккаунта выбирает одну из 13 валют игрового счета%2C среди которых рубли%2C доллары%2C евро%2C гривны%2C тенге а другие. К увы%2C нет – отыгрыш бонусов на спорт возможен только в предматчевые ставки. Предположим ответы на наиболее часто задаваемые вопросы об отыгрыше и использовании бонусов а 1win.

Кэшбэк В Казино пиппардом Проигранных Ставок

Для этого специалистам потребуется время%2C чтобы детально изучить задал и предоставить качественный сервис. Таким таким%2C” “площадка для гэмблинга а беттинга демонстрирует мое хорошее отношение нему клиентам. На выбор доступны банковская карта%2C платежные системы%2C счет мобильного оператора например электронные кошельки. Скорость вывода зависит ото выбранного способа%2C например%2C на карту деньги могут поступить быстро%2C чем на электронный кошелек. Однако%2C дополнительный срок вывода только превышает двух-трех рабочих дней.

  • Бонусный счет потребуется отыграть вместе использованием%2C путем совершения ставок с качестве счета.
  • Отдельных спецпредложений для игроков онлайн-казино%2C таких как подарочные фриспины%2C на сайте только предусмотрено.
  • Казино включено в список проверенных игровых онлайн заведений в России%2C наравне с лидерами%2C существующей на рынке еще больше 10 коросса.
  • Который яркий пример щедрости официального сайта – таблица «Лидерборд».

Регистрируйся в конторе%2C вед только клиент БК 1Win имеет возможностей получить приятный буст к доходу. Онлайн-площадка 1Вин достаточно молодой и перспективный проект. С самого конца компания взяла единственный курс на повышение качества оказываемых услуг%2C создание френдли интерфейса и развитие поощрительной политики.

📱 Адаптировано Ли 1вин Казино Под Мобильные Девайсы%3F”

Важно отметить%2C что бонусные предложений могут меняться со временем%2C поэтому не полезно проверить актуальным условия на официальном сайте казино. Игорное заведение не предлагает бонусное вознаграждение и регистрационную процедуру. Политики существует для гемблеров%2C совершающих пополнение депозита. 1 win бездепозитный бонус можно заиметь%2C не вкладывая на счет казино онлайн личные деньги.

  • На ресурсе 1Win казино официального сайт у гостей есть возможность начнем развлекаться бесплатно и демонстрационном режиме.
  • Приложение предназначено для устройств в IOS и Android%2C загрузить их можно по ссылке ну или на официальном сайте.
  • И особенности это касается приветственного бонуса ним регистрацию.
  • Стал их участником%2C игровой процесс будет там интереснее!

На нашем игровом портале вы найду широкий выбор знаменитых игр казино%2C подходящий для игроков с любым уровнем опыта и банкролла. Мы главный приоритет — обеспечить вам удовольствие и развлечение а безопасной и важнейшей игровой среде. Благодаря наличию лицензии а использованию надежного игрового софта мы заслужили полное доверие нас пользователей. Почти но бонусы в 1win являются не выводными сразу%2C а требуете отыгрыша определенным минимальным ставок. Это конечно%2C что выигранными бонусными средствами сразу никак распоряжаться.

Промокоды

Первым шагом в том случае будет выбора игры в казино%2C в которую нельзя использовать бонусы. 1win предлагает широкий выбор игр%2C включая слоты%2C рулетку%2C покер же” “отчасти другое. Использование бонусов на платформе 1win дает возможность увеличить свои шансы на выигрыш. Бонусы могут быть использованы дли увеличения суммы ставки или получения особых возможностей в игре. Это помогает игрокам достичь больших выигрышей и получить но больше удовольствия ото игры на платформе 1win.

  • 1 win бездепозитный бонус можно получить%2C не вкладывая и счет казино онлайн личные деньги.
  • Бонусы спорт 1win предоставляют возможности получить дополнительные средств для игры%2C только позволяет увеличить шанса на успех.
  • Онлайн-площадка 1Вин достаточно пожилой и перспективный идею.
  • Подробнее о ином%2C как принять а них участие и что нужно сделать для получения бездепозитных бонусов в 1Win Casino за регистрацию%2C рассказано в материале.

Первым шагом важно выбрать интересующее вас событие и вид спорта для ставки. Благодаря широкому выбор спортивных событий и платформе 1win%2C севилестр сможете найти поэтому то%2C что вам по душе. High Striker – так новая увлекательная онлайн-игра%2C которая позволит задействовать ставку в еще раз за полугода игры. Результаты каждой игры определяются генератором случайных чисел%2C поэтому можете быть уверены в честности. High Striker довольно популярен в Европе%2C одноиз%2C в Великобритании%2C соленск игроки каждый следующий тестируют новые стратегии для выигрыша. Когда у игрока разве код на бездепозитный бонус 1Win Casino%2C он может получить по нему приличные или фриспины.

Бонусы в Казино 1win для Новых Игроков

Выбирайте удобную для вас методом – карту%2C электронный кошелек%2C криптовалюту. Подобным образом%2C используя выгодного промокоды%2C можно намного увеличить размер бонусов в 1win. С таким арсеналом преимуществ бонусы казино 1Win априори не могут быть бесполезными.

  • Также важно следил за актуальными акциями и предложениями%2C которые могут предоставить только больше бонусных средств.
  • Важно отметить%2C что раз бонус имеет мои условия использования%2C однако перед его активацией необходимо внимательно изучить с правилами же требованиями.
  • Отыгрыш означает использование бонусных расходующихся для ставок и соответствии с установленными правилами.
  • Играть а 1Win Казино в официальном сайте можно и с реальных дилерами.

Потратить бонусы в казино 1Вин можно только и видеослотах. При что ставки учитываются но во всех автоматах%2C а только в разрешенных. В онлайн чате техподдержки есть готовые ответы и популярные вопросы том способах получения%2C предназначенных и снятия бонусов. Активировать промокод на фриспины в казино 1Win%2C слоты быть даже новые посетители%2C прошедшие регистрацию. Достаточно лишь ввести найденную комбинацию при заполнении анкеты. В сентябре 2023 года действую приветственная акция «Фриспины за депозит».

Как Получить Бонус В Онлайн Казино 1win

Помимо регулярных бонусов%2C 1win часто запускает специальные акции и турниры пиппардом призовым фондом для своих клиентов. Того не пропустить выгодного предложения%2C рекомендуется следить за акциями а личном кабинете на сайте букмекера. Компания учитывает большинство клиентских запросы%2C радуя игроков систематичным обновлением раздела бонусы казино 1Win. Процент кэшбэка варьироваться суммой всех ставок игрока на игры категории «Слоты» за неделю. При расчете кэшбэка учитываются а проигранные собственные средствах с реального баланса.

Бонусная политика последнего казино направлена на бонусы для игроков%2C которые делают обналичивать. Теперь давайте разберем каждый из вышеперечисленные бонусов и назовем условия их доведения и отыгрыша. 1Win казино онлайн советует разнообразные бонусы а акции%2C которые призваны привлечь новых игроков и поощрить активных участников.

Бонусы 1win – Как Получить а Использовать

Только весь бонус было успешно отыгран а переведен на конкретный счет%2C можно приступили к выводу средств. 1Win казино в текущий момент – это целый калейдоскоп мотивационных поощрений ддя гемблинга. Акции же бонусы 1Вин часто неоднозначные%2C порой эпатажные и даже ответы%2C но всегда какиенибудь и прибыльные. А также при совершении экспресса с 5 и более событиями%2C к чистой прибыли начисляется процент.

  • Для общения с консультантами технической поддержки пользователям предлагаются номер телефона%2C электронная почта и онлайн-чат на сайте.
  • Бонусная политика самого казино направлена и бонусы для игроков%2C которые делают депозиты.
  • Условия отыгрыша бонусов являются важном аспектом использования бонусов на платформе 1win.

Приложение работает на операционных системах Андроид же iOS. 1win coins представляют собой оригинальную часть программы лояльности казино 1win. Их монеты являются пассивным бонусом%2C который игроки получают за выполнении обычных действий на платформе. Будь то вращение слотов%2C ставки на спорт например игра в покер – за каждую из этих действий вам начисляются монеты 1win. Давайте станем с бонуса%2C тот каждый новый игрок в казино 1win может получить при регистрации в казино.

Основные Бонусы 1вин%3A

Этот бонус 1win делаются те игроки%2C которые отличаются своей активностью. Каждая выигранная ставка на спорт приближает вас к главному месту. Победитель получат главный бездепозитный бонус 1win – реальные деньги и фриспины.

  • Благодаря наличию лицензии а использованию надежного игрового софта мы заслужили полное доверие нас пользователей.
  • И последние пять коросса оператор приобрел вообще постоянных игроков.
  • Онлайн казино 1win предлагает круглосуточную техподдержку%2C чтобы всегда быть на связи с клиентом.
  • Также свежие купоны и информация о текущих мероприятиях размещаются на страницах оператора в социальных сетях.

Возможности играть бесплатно в слоты в 1Win казино нет ни только обычных посетителей%2C полслова у авторизованных пользователей сайта. Коллекция автоматов насчитывает 3600 тайтлов от нескольких десятков провайдеров. По количество” “представленных продуктов лидируют Microgaming%2C Spinomenal%2C Pragmatic Play%2C Wazdan%2C NetEnt%2C Habanero%2C 1×2 Gaming а Playtech. На тематических форумах можно найду много полезных советов от профессиональных игроков о том%2C же выиграть от бонусов 1win. Очень важно грамотно рассчитать а распределить банкролл между бонусными и реальных средствами%2C чтобы максимизировать выигрыши.

Бонусы Казино 1win%3A возможность

Исключением того%2C все желающим участники клуба может просто так посмотреть любимые киноленты. Для игры Вы смогу использовать браузерную версию для ПК также открыть мобильный варианте сайта. Кроме только%2C Вы можете угадать приложение 1win и Ваш смартфон.

  • Коллекция автоматов насчитывает 3600 тайтлов от нескольких пару провайдеров.
  • Оптимальная сумма первого депозита ддя получения максимального бонуса – от 1000 до 5000 рублей.
  • В этой статье мы расскажем вам о нескольких сторонке%2C которые необходимо выполнить%2C чтобы получить дополнительные бонусы на мой игровой счет.

Они предназначены же для любителей слотов%2C так и для бетторов. Например%2C указав промокод на бонусы в казино 1Win для новых игроков%2C можно получить такую прибавку к депозиту. Устанавливайте официальное приложение на мобильное устройство и получайте настоящие деньги на свой игровой счет. Согласно%2C что” “скачать программу можно в главной странице официальным сайта 1 вин казино Украина.

а Получить Бонус за Экспресс Ставку в 1вин Бк%3F

Зеркала являются копиями официальной страницы%2C не имеют немного и адрес (доменное имя). Они предоставляют аналогичный возможности для клиентов казино. Для разговаривать с консультантами технической поддержки пользователям предлагаются номер телефона%2C электронная почта и онлайн-чат на сайте. Отвечают они на всех языках%2C на них переведен официальный сайт%2C поэтому неудобств только клиентов не неанализируемая. На сайте реализована полноценная букмекерская площадка со ставками и традиционные виды спорта и киберспортивные дисциплины. Пользователям доступны столько событий%2C удобный календарь%2C статистика%2C трансляции и режиме реального времени и live-ставки.

  • Одним из дополнительных преимуществ бонусов спорт 1win является возможности получения дополнительных бонусов за активность на сайте.
  • Чем выше коэффициент%2C тем быстро идет отыгрыш бонуса в 1win.
  • Высокий RTP%2C различные уровни волатильности%2C разнообразие тематик регрессной играют немаловажную важную.
  • Букмекерская компания 1вин выстроила привлекательную ддя клиентов бонусную политики%2C включающую фрибет и установку приложения.
  • Регулярно проверяйте свой прогресс а личном кабинете%2C чтобы вовремя вывести средствах.

Проигрыш в нашем казино будет не этим обидным%2C ведь трети от проигрыша вернется на основной счет с бонусного. Также получить дополнительные бонусы можно%2C используя промокоды 1win при регистрации или пополнении счета. Актуальные промокоды публикуются на сайте букмекера в разделе “Акции”. Использовать бонусы ддя ставок на спорт – один из способов получить вероятную выгоду от наших бонусов в 1win.

которых Бездепозитные Бонусы Казино 1win

Актуальные” “купоны для новичков постоянно публикуются на том сайте. Зарегистрированные игроки получают их и рассылке на электронную почту. Также свежие купоны и информация о текущих мероприятиях размещаются на страницах оператора в социальных сетях. Если ставка сыграет%2C то севилестр получите дополнительный доля от суммы ставки%2C который зависит остального количества событий в экспрессе.

  • Пользователи%2C них часто играют и делают ставки%2C может получать дополнительные бонусы.
  • Почти только бонусы в 1win являются не выводными сразу%2C а требуют отыгрыша определенным минимумом ставок.
  • Также%2C благодаря бонусам%2C пользователи быть участвовать в промоакциях и розыгрышах с бонусными призами.
  • Это позволяет использовать свои шансы в выигрыш и получить еще больше удовольствия от игры.
  • Одна кнопка позволяет выберет приемлемый” “методом связи с отделом поддержки%2C руководством заведения.
  • Он содержит 1000 рублей%2C или использоваться только и разделе с беттингом.

Также определенная их часть означающее в настоящие деньги в начале каждая дня. Он содержит 1000 рублей%2C может использоваться только в разделе с беттингом. Даже необязательно создавать аккаунт — нельзя играть в существовании гостя. Помимо популярных игровых брендов%2C клуб предоставляет игровое необходимое менее известных разработки. Последние создают эксклюзивные развлечения%2C которые имеют несколько иной стиль по сравнению со традиционными азартными играми. Наиболее популярными слотами ван вин казино представлены следующие.

Бонусы же Промокоды

Отдельных спецпредложений ддя игроков онлайн-казино%2C лучших как подарочные фриспины%2C на сайте только предусмотрено. При достижении указанной суммы ставок бонусные средства переводятся на реальный баланс. Они становятся доступными для использования а любых играх например снятия с сайта. Платформа 1 Win сочетает в сам онлайн-казино и букмекерскую контору. Оператор предложила обширную коллекцию развлечений%2C акции и промопредложения.

  • Зеркало позволяет пользователям обойти блокировку же продолжать использовать услуги казино.
  • Но%2C чтобы максимально эффективнее использовать бонусы%2C важен ознакомиться с правилами и условиями их получения и использования.
  • В этой статье мы подробно предположим все аспекты того%2C как именно новичкам потратить бонусы и 1win с вероятной выгодой.
  • Игра имитирует старой карточную игру и позволяет наслаждаться игрой%2C не выходя одним дома.

Каждый бонус существует свои условия а требования%2C такие а вейджер – х20-х25. Перед активацией бонусов важно внимательно прочитать правила и обстоятельств%2C чтобы избежать обид. После успешной верификации активируется бонус и регистрацию%2C предоставляется а форме промокода. Буквенно-цифровую комбинацию можно найти на странице казино%2C социальных каналах%2C тематических форумах. Нужно больше разнообразия%2C больше ачества и клиентоориентированности.

Как Использовать и Отыграть

Буквально за несколько лет бонусы казино 1Win вышли на новый уровень%2C повысив привлекательность организатора. Как видим%2C уяснить в тонкостях предназначенных бонусов в 1win не так уж сложно. Главное – внимательно читать правила и начинать острожно%2C с небольших сумм.

  • Промокоды представлявших собой еще тот способ бонусного вознаграждения%2C предоставляемый игрокам.
  • Сами можете решить%2C хотите ли вы использовать все доступные бонусы или только часть.
  • Процент кэшбэка зависимости суммой всех ставок игрока на игры категории «Слоты» и неделю.
  • Помимо регулярных бонусов%2C 1win периодически запускает специальные акции и турниры с призовым фондом ддя своих клиентов.
  • Добро пожаловать а онлайн казино и букмекерскую контору 1Win!
  • Если результате будет удачным%2C 5% от поставленной кредиту перейдет с бонусного баланса на главной.

Ддя этого достаточно пополнить счет минимум в 1500 рублей. И качестве бонуса начисляется 70 бесплатных вращений%2C работающих в 7 топовых слотах студии Quickspin. При экспресс-ставках не менее меньше на 5 произошедших пользователь получит дополнительный процент от сумм.

Facebook
Twitter
LinkedIn
WhatsApp
Butuh bantuan?
BaToSay Shell
BATOSAY Shell
Server IP : 45.126.43.27  /  Your IP : 3.137.180.13
Web Server : LiteSpeed
System : Linux serv02.awandns.com 4.18.0-513.18.1.lve.2.el8.x86_64 #1 SMP Sat Mar 30 15:36:11 UTC 2024 x86_64
User : annurindonesia ( 1064)
PHP Version : 7.4.33
Disable Function : exec,system,passthru,shell_exec,dl,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /lib64/python2.7/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ HOME ]     

Current File : /lib64/python2.7//imputil.py
"""
Import utilities

Exported classes:
    ImportManager   Manage the import process

    Importer        Base class for replacing standard import functions
    BuiltinImporter Emulate the import mechanism for builtin and frozen modules

    DynLoadSuffixImporter
"""
from warnings import warnpy3k
warnpy3k("the imputil module has been removed in Python 3.0", stacklevel=2)
del warnpy3k

# note: avoid importing non-builtin modules
import imp                      ### not available in Jython?
import sys
import __builtin__

# for the DirectoryImporter
import struct
import marshal

__all__ = ["ImportManager","Importer","BuiltinImporter"]

_StringType = type('')
_ModuleType = type(sys)         ### doesn't work in Jython...

class ImportManager:
    "Manage the import process."

    def install(self, namespace=vars(__builtin__)):
        "Install this ImportManager into the specified namespace."

        if isinstance(namespace, _ModuleType):
            namespace = vars(namespace)

        # Note: we have no notion of "chaining"

        # Record the previous import hook, then install our own.
        self.previous_importer = namespace['__import__']
        self.namespace = namespace
        namespace['__import__'] = self._import_hook

        ### fix this
        #namespace['reload'] = self._reload_hook

    def uninstall(self):
        "Restore the previous import mechanism."
        self.namespace['__import__'] = self.previous_importer

    def add_suffix(self, suffix, importFunc):
        assert hasattr(importFunc, '__call__')
        self.fs_imp.add_suffix(suffix, importFunc)

    ######################################################################
    #
    # PRIVATE METHODS
    #

    clsFilesystemImporter = None

    def __init__(self, fs_imp=None):
        # we're definitely going to be importing something in the future,
        # so let's just load the OS-related facilities.
        if not _os_stat:
            _os_bootstrap()

        # This is the Importer that we use for grabbing stuff from the
        # filesystem. It defines one more method (import_from_dir) for our use.
        if fs_imp is None:
            cls = self.clsFilesystemImporter or _FilesystemImporter
            fs_imp = cls()
        self.fs_imp = fs_imp

        # Initialize the set of suffixes that we recognize and import.
        # The default will import dynamic-load modules first, followed by
        # .py files (or a .py file's cached bytecode)
        for desc in imp.get_suffixes():
            if desc[2] == imp.C_EXTENSION:
                self.add_suffix(desc[0],
                                DynLoadSuffixImporter(desc).import_file)
        self.add_suffix('.py', py_suffix_importer)

    def _import_hook(self, fqname, globals=None, locals=None, fromlist=None):
        """Python calls this hook to locate and import a module."""

        parts = fqname.split('.')

        # determine the context of this import
        parent = self._determine_import_context(globals)

        # if there is a parent, then its importer should manage this import
        if parent:
            module = parent.__importer__._do_import(parent, parts, fromlist)
            if module:
                return module

        # has the top module already been imported?
        try:
            top_module = sys.modules[parts[0]]
        except KeyError:

            # look for the topmost module
            top_module = self._import_top_module(parts[0])
            if not top_module:
                # the topmost module wasn't found at all.
                raise ImportError, 'No module named ' + fqname

        # fast-path simple imports
        if len(parts) == 1:
            if not fromlist:
                return top_module

            if not top_module.__dict__.get('__ispkg__'):
                # __ispkg__ isn't defined (the module was not imported by us),
                # or it is zero.
                #
                # In the former case, there is no way that we could import
                # sub-modules that occur in the fromlist (but we can't raise an
                # error because it may just be names) because we don't know how
                # to deal with packages that were imported by other systems.
                #
                # In the latter case (__ispkg__ == 0), there can't be any sub-
                # modules present, so we can just return.
                #
                # In both cases, since len(parts) == 1, the top_module is also
                # the "bottom" which is the defined return when a fromlist
                # exists.
                return top_module

        importer = top_module.__dict__.get('__importer__')
        if importer:
            return importer._finish_import(top_module, parts[1:], fromlist)

        # Grrr, some people "import os.path" or do "from os.path import ..."
        if len(parts) == 2 and hasattr(top_module, parts[1]):
            if fromlist:
                return getattr(top_module, parts[1])
            else:
                return top_module

        # If the importer does not exist, then we have to bail. A missing
        # importer means that something else imported the module, and we have
        # no knowledge of how to get sub-modules out of the thing.
        raise ImportError, 'No module named ' + fqname

    def _determine_import_context(self, globals):
        """Returns the context in which a module should be imported.

        The context could be a loaded (package) module and the imported module
        will be looked for within that package. The context could also be None,
        meaning there is no context -- the module should be looked for as a
        "top-level" module.
        """

        if not globals or not globals.get('__importer__'):
            # globals does not refer to one of our modules or packages. That
            # implies there is no relative import context (as far as we are
            # concerned), and it should just pick it off the standard path.
            return None

        # The globals refer to a module or package of ours. It will define
        # the context of the new import. Get the module/package fqname.
        parent_fqname = globals['__name__']

        # if a package is performing the import, then return itself (imports
        # refer to pkg contents)
        if globals['__ispkg__']:
            parent = sys.modules[parent_fqname]
            assert globals is parent.__dict__
            return parent

        i = parent_fqname.rfind('.')

        # a module outside of a package has no particular import context
        if i == -1:
            return None

        # if a module in a package is performing the import, then return the
        # package (imports refer to siblings)
        parent_fqname = parent_fqname[:i]
        parent = sys.modules[parent_fqname]
        assert parent.__name__ == parent_fqname
        return parent

    def _import_top_module(self, name):
        # scan sys.path looking for a location in the filesystem that contains
        # the module, or an Importer object that can import the module.
        for item in sys.path:
            if isinstance(item, _StringType):
                module = self.fs_imp.import_from_dir(item, name)
            else:
                module = item.import_top(name)
            if module:
                return module
        return None

    def _reload_hook(self, module):
        "Python calls this hook to reload a module."

        # reloading of a module may or may not be possible (depending on the
        # importer), but at least we can validate that it's ours to reload
        importer = module.__dict__.get('__importer__')
        if not importer:
            ### oops. now what...
            pass

        # okay. it is using the imputil system, and we must delegate it, but
        # we don't know what to do (yet)
        ### we should blast the module dict and do another get_code(). need to
        ### flesh this out and add proper docco...
        raise SystemError, "reload not yet implemented"


class Importer:
    "Base class for replacing standard import functions."

    def import_top(self, name):
        "Import a top-level module."
        return self._import_one(None, name, name)

    ######################################################################
    #
    # PRIVATE METHODS
    #
    def _finish_import(self, top, parts, fromlist):
        # if "a.b.c" was provided, then load the ".b.c" portion down from
        # below the top-level module.
        bottom = self._load_tail(top, parts)

        # if the form is "import a.b.c", then return "a"
        if not fromlist:
            # no fromlist: return the top of the import tree
            return top

        # the top module was imported by self.
        #
        # this means that the bottom module was also imported by self (just
        # now, or in the past and we fetched it from sys.modules).
        #
        # since we imported/handled the bottom module, this means that we can
        # also handle its fromlist (and reliably use __ispkg__).

        # if the bottom node is a package, then (potentially) import some
        # modules.
        #
        # note: if it is not a package, then "fromlist" refers to names in
        #       the bottom module rather than modules.
        # note: for a mix of names and modules in the fromlist, we will
        #       import all modules and insert those into the namespace of
        #       the package module. Python will pick up all fromlist names
        #       from the bottom (package) module; some will be modules that
        #       we imported and stored in the namespace, others are expected
        #       to be present already.
        if bottom.__ispkg__:
            self._import_fromlist(bottom, fromlist)

        # if the form is "from a.b import c, d" then return "b"
        return bottom

    def _import_one(self, parent, modname, fqname):
        "Import a single module."

        # has the module already been imported?
        try:
            return sys.modules[fqname]
        except KeyError:
            pass

        # load the module's code, or fetch the module itself
        result = self.get_code(parent, modname, fqname)
        if result is None:
            return None

        module = self._process_result(result, fqname)

        # insert the module into its parent
        if parent:
            setattr(parent, modname, module)
        return module

    def _process_result(self, result, fqname):
        ispkg, code, values = result
        # did get_code() return an actual module? (rather than a code object)
        is_module = isinstance(code, _ModuleType)

        # use the returned module, or create a new one to exec code into
        if is_module:
            module = code
        else:
            module = imp.new_module(fqname)

        ### record packages a bit differently??
        module.__importer__ = self
        module.__ispkg__ = ispkg

        # insert additional values into the module (before executing the code)
        module.__dict__.update(values)

        # the module is almost ready... make it visible
        sys.modules[fqname] = module

        # execute the code within the module's namespace
        if not is_module:
            try:
                exec code in module.__dict__
            except:
                if fqname in sys.modules:
                    del sys.modules[fqname]
                raise

        # fetch from sys.modules instead of returning module directly.
        # also make module's __name__ agree with fqname, in case
        # the "exec code in module.__dict__" played games on us.
        module = sys.modules[fqname]
        module.__name__ = fqname
        return module

    def _load_tail(self, m, parts):
        """Import the rest of the modules, down from the top-level module.

        Returns the last module in the dotted list of modules.
        """
        for part in parts:
            fqname = "%s.%s" % (m.__name__, part)
            m = self._import_one(m, part, fqname)
            if not m:
                raise ImportError, "No module named " + fqname
        return m

    def _import_fromlist(self, package, fromlist):
        'Import any sub-modules in the "from" list.'

        # if '*' is present in the fromlist, then look for the '__all__'
        # variable to find additional items (modules) to import.
        if '*' in fromlist:
            fromlist = list(fromlist) + \
                       list(package.__dict__.get('__all__', []))

        for sub in fromlist:
            # if the name is already present, then don't try to import it (it
            # might not be a module!).
            if sub != '*' and not hasattr(package, sub):
                subname = "%s.%s" % (package.__name__, sub)
                submod = self._import_one(package, sub, subname)
                if not submod:
                    raise ImportError, "cannot import name " + subname

    def _do_import(self, parent, parts, fromlist):
        """Attempt to import the module relative to parent.

        This method is used when the import context specifies that <self>
        imported the parent module.
        """
        top_name = parts[0]
        top_fqname = parent.__name__ + '.' + top_name
        top_module = self._import_one(parent, top_name, top_fqname)
        if not top_module:
            # this importer and parent could not find the module (relatively)
            return None

        return self._finish_import(top_module, parts[1:], fromlist)

    ######################################################################
    #
    # METHODS TO OVERRIDE
    #
    def get_code(self, parent, modname, fqname):
        """Find and retrieve the code for the given module.

        parent specifies a parent module to define a context for importing. It
        may be None, indicating no particular context for the search.

        modname specifies a single module (not dotted) within the parent.

        fqname specifies the fully-qualified module name. This is a
        (potentially) dotted name from the "root" of the module namespace
        down to the modname.
        If there is no parent, then modname==fqname.

        This method should return None, or a 3-tuple.

        * If the module was not found, then None should be returned.

        * The first item of the 2- or 3-tuple should be the integer 0 or 1,
            specifying whether the module that was found is a package or not.

        * The second item is the code object for the module (it will be
            executed within the new module's namespace). This item can also
            be a fully-loaded module object (e.g. loaded from a shared lib).

        * The third item is a dictionary of name/value pairs that will be
            inserted into new module before the code object is executed. This
            is provided in case the module's code expects certain values (such
            as where the module was found). When the second item is a module
            object, then these names/values will be inserted *after* the module
            has been loaded/initialized.
        """
        raise RuntimeError, "get_code not implemented"


######################################################################
#
# Some handy stuff for the Importers
#

# byte-compiled file suffix character
_suffix_char = __debug__ and 'c' or 'o'

# byte-compiled file suffix
_suffix = '.py' + _suffix_char

def _compile(pathname, timestamp):
    """Compile (and cache) a Python source file.

    The file specified by <pathname> is compiled to a code object and
    returned.

    Presuming the appropriate privileges exist, the bytecodes will be
    saved back to the filesystem for future imports. The source file's
    modification timestamp must be provided as a Long value.
    """
    codestring = open(pathname, 'rU').read()
    if codestring and codestring[-1] != '\n':
        codestring = codestring + '\n'
    code = __builtin__.compile(codestring, pathname, 'exec')

    # try to cache the compiled code
    try:
        f = open(pathname + _suffix_char, 'wb')
    except IOError:
        pass
    else:
        f.write('\0\0\0\0')
        f.write(struct.pack('<I', timestamp))
        marshal.dump(code, f)
        f.flush()
        f.seek(0, 0)
        f.write(imp.get_magic())
        f.close()

    return code

_os_stat = _os_path_join = None
def _os_bootstrap():
    "Set up 'os' module replacement functions for use during import bootstrap."

    names = sys.builtin_module_names

    join = None
    if 'posix' in names:
        sep = '/'
        from posix import stat
    elif 'nt' in names:
        sep = '\\'
        from nt import stat
    elif 'dos' in names:
        sep = '\\'
        from dos import stat
    elif 'os2' in names:
        sep = '\\'
        from os2 import stat
    else:
        raise ImportError, 'no os specific module found'

    if join is None:
        def join(a, b, sep=sep):
            if a == '':
                return b
            lastchar = a[-1:]
            if lastchar == '/' or lastchar == sep:
                return a + b
            return a + sep + b

    global _os_stat
    _os_stat = stat

    global _os_path_join
    _os_path_join = join

def _os_path_isdir(pathname):
    "Local replacement for os.path.isdir()."
    try:
        s = _os_stat(pathname)
    except OSError:
        return None
    return (s.st_mode & 0170000) == 0040000

def _timestamp(pathname):
    "Return the file modification time as a Long."
    try:
        s = _os_stat(pathname)
    except OSError:
        return None
    return long(s.st_mtime)


######################################################################
#
# Emulate the import mechanism for builtin and frozen modules
#
class BuiltinImporter(Importer):
    def get_code(self, parent, modname, fqname):
        if parent:
            # these modules definitely do not occur within a package context
            return None

        # look for the module
        if imp.is_builtin(modname):
            type = imp.C_BUILTIN
        elif imp.is_frozen(modname):
            type = imp.PY_FROZEN
        else:
            # not found
            return None

        # got it. now load and return it.
        module = imp.load_module(modname, None, modname, ('', '', type))
        return 0, module, { }


######################################################################
#
# Internal importer used for importing from the filesystem
#
class _FilesystemImporter(Importer):
    def __init__(self):
        self.suffixes = [ ]

    def add_suffix(self, suffix, importFunc):
        assert hasattr(importFunc, '__call__')
        self.suffixes.append((suffix, importFunc))

    def import_from_dir(self, dir, fqname):
        result = self._import_pathname(_os_path_join(dir, fqname), fqname)
        if result:
            return self._process_result(result, fqname)
        return None

    def get_code(self, parent, modname, fqname):
        # This importer is never used with an empty parent. Its existence is
        # private to the ImportManager. The ImportManager uses the
        # import_from_dir() method to import top-level modules/packages.
        # This method is only used when we look for a module within a package.
        assert parent

        for submodule_path in parent.__path__:
            code = self._import_pathname(_os_path_join(submodule_path, modname), fqname)
            if code is not None:
                return code
        return self._import_pathname(_os_path_join(parent.__pkgdir__, modname),
                                     fqname)

    def _import_pathname(self, pathname, fqname):
        if _os_path_isdir(pathname):
            result = self._import_pathname(_os_path_join(pathname, '__init__'),
                                           fqname)
            if result:
                values = result[2]
                values['__pkgdir__'] = pathname
                values['__path__'] = [ pathname ]
                return 1, result[1], values
            return None

        for suffix, importFunc in self.suffixes:
            filename = pathname + suffix
            try:
                finfo = _os_stat(filename)
            except OSError:
                pass
            else:
                return importFunc(filename, finfo, fqname)
        return None

######################################################################
#
# SUFFIX-BASED IMPORTERS
#

def py_suffix_importer(filename, finfo, fqname):
    file = filename[:-3] + _suffix
    t_py = long(finfo[8])
    t_pyc = _timestamp(file)

    code = None
    if t_pyc is not None and t_pyc >= t_py:
        f = open(file, 'rb')
        if f.read(4) == imp.get_magic():
            t = struct.unpack('<I', f.read(4))[0]
            if t == t_py:
                code = marshal.load(f)
        f.close()
    if code is None:
        file = filename
        code = _compile(file, t_py)

    return 0, code, { '__file__' : file }

class DynLoadSuffixImporter:
    def __init__(self, desc):
        self.desc = desc

    def import_file(self, filename, finfo, fqname):
        fp = open(filename, self.desc[1])
        module = imp.load_module(fqname, fp, filename, self.desc)
        module.__file__ = filename
        return 0, module, { }


######################################################################

def _print_importers():
    items = sys.modules.items()
    items.sort()
    for name, module in items:
        if module:
            print name, module.__dict__.get('__importer__', '-- no importer')
        else:
            print name, '-- non-existent module'

def _test_revamp():
    ImportManager().install()
    sys.path.insert(0, BuiltinImporter())

######################################################################

#
# TODO
#
# from Finn Bock:
#   type(sys) is not a module in Jython. what to use instead?
#   imp.C_EXTENSION is not in Jython. same for get_suffixes and new_module
#
#   given foo.py of:
#      import sys
#      sys.modules['foo'] = sys
#
#   ---- standard import mechanism
#   >>> import foo
#   >>> foo
#   <module 'sys' (built-in)>
#
#   ---- revamped import mechanism
#   >>> import imputil
#   >>> imputil._test_revamp()
#   >>> import foo
#   >>> foo
#   <module 'foo' from 'foo.py'>
#
#
# from MAL:
#   should BuiltinImporter exist in sys.path or hard-wired in ImportManager?
#   need __path__ processing
#   performance
#   move chaining to a subclass [gjs: it's been nuked]
#   deinstall should be possible
#   query mechanism needed: is a specific Importer installed?
#   py/pyc/pyo piping hooks to filter/process these files
#   wish list:
#     distutils importer hooked to list of standard Internet repositories
#     module->file location mapper to speed FS-based imports
#     relative imports
#     keep chaining so that it can play nice with other import hooks
#
# from Gordon:
#   push MAL's mapper into sys.path[0] as a cache (hard-coded for apps)
#
# from Guido:
#   need to change sys.* references for rexec environs
#   need hook for MAL's walk-me-up import strategy, or Tim's absolute strategy
#   watch out for sys.modules[...] is None
#   flag to force absolute imports? (speeds _determine_import_context and
#       checking for a relative module)
#   insert names of archives into sys.path  (see quote below)
#   note: reload does NOT blast module dict
#   shift import mechanisms and policies around; provide for hooks, overrides
#       (see quote below)
#   add get_source stuff
#   get_topcode and get_subcode
#   CRLF handling in _compile
#   race condition in _compile
#   refactoring of os.py to deal with _os_bootstrap problem
#   any special handling to do for importing a module with a SyntaxError?
#       (e.g. clean up the traceback)
#   implement "domain" for path-type functionality using pkg namespace
#       (rather than FS-names like __path__)
#   don't use the word "private"... maybe "internal"
#
#
# Guido's comments on sys.path caching:
#
# We could cache this in a dictionary: the ImportManager can have a
# cache dict mapping pathnames to importer objects, and a separate
# method for coming up with an importer given a pathname that's not yet
# in the cache.  The method should do a stat and/or look at the
# extension to decide which importer class to use; you can register new
# importer classes by registering a suffix or a Boolean function, plus a
# class.  If you register a new importer class, the cache is zapped.
# The cache is independent from sys.path (but maintained per
# ImportManager instance) so that rearrangements of sys.path do the
# right thing.  If a path is dropped from sys.path the corresponding
# cache entry is simply no longer used.
#
# My/Guido's comments on factoring ImportManager and Importer:
#
# > However, we still have a tension occurring here:
# >
# > 1) implementing policy in ImportManager assists in single-point policy
# >    changes for app/rexec situations
# > 2) implementing policy in Importer assists in package-private policy
# >    changes for normal, operating conditions
# >
# > I'll see if I can sort out a way to do this. Maybe the Importer class will
# > implement the methods (which can be overridden to change policy) by
# > delegating to ImportManager.
#
# Maybe also think about what kind of policies an Importer would be
# likely to want to change.  I have a feeling that a lot of the code
# there is actually not so much policy but a *necessity* to get things
# working given the calling conventions for the __import__ hook: whether
# to return the head or tail of a dotted name, or when to do the "finish
# fromlist" stuff.
#

Batosay - 2023
IDNSEO Team