Python 3.10触ってみた(1) ~asyncio#get_event_loop
こんにちは, ミュージシャンの卵です.
Python3.10のリリース予定日の2021-10-04が近づいていますね。 そろそろどの辺が変わるのかも含めて調査を始めています。 asyncioのコードを書いてみて軽い変更があったことを見つけました。
asyncio
Python3.10でasyncioのコードを書いてみたらこんなwarningが出るようになりました。
import asyncio async def main(): print('Hello ...') await asyncio.sleep(1) print('... World!') loop = asyncio.get_event_loop() # ここでwarning loop.run_until_complete(main())
DeprecationWarning: There is no current event loop loop = asyncio.get_event_loop()
調べた感じだとこういうことらしい
asyncio.get_event_loop() now emits a deprecation warning if there is no running event loop. In the future it will be an alias of get_running_loop(). asyncio functions which implicitly create a Future or Task objects now emit a deprecation warning if there is no running event loop and no explicit loop argument is passed: ensure_future(), wrap_future(), gather(), shield(), as_completed() and constructors of Future, Task, StreamReader, StreamReaderProtocol. (Contributed by Serhiy Storchaka in bpo-39529.)
ざっくり訳すと
asyncio.get_event_loop()は、実行中のイベントループがない場合、 deprecationの警告を出すようになりました。asyncio.get_event_loop() は、将来的には get_running_loop() のエイリアスになります。
というわけで asyncio.get_event_loop()
を呼ぶとこの警告が出るっぽい。
対策
どうやら asyncio.run
だとこのwarningが出ないことがわかってきた。
というわけで サクッとサンプルを書きたい時は asyncio.run()
を使い、
そうじゃない時はこんな感じでnew_event_loop -> set_event_loopするのが良いっぽい。
import asyncio # ものすごく略したコード loop = asyncio.new_event_loop() try: asyncio.set_event_loop(loop) loop.run_until_complete(main()) finally: asyncio.set_event_loop(None) loop.close()
ソフトウェアの捨てられビリティ(Disposabiliy) 2021
こんにちは、魅惑の何かです。秋の夜長にポエムでも描いてみました。
夜にmagnoliakさんのこの辺のツイートをみててアウトプットしたいものを思い出したので忘れずに書いておきます。
本当に必要なビジネスロジック以外はいつでも捨てられるように処理を書くのがいいんじゃないかなと思い続けている。個人的には 捨てられビリティ とか呼んでる。捨てられビリティ が低いと後に変更が厳しくなりがち的な
— Nakamura Masato (@Masahito) 2021年3月6日
背景
初期開発、リリース後に変更を加えていくことで変更のコストが大変になることが多い。
また途中で開発の(いろんな意味での)事情がかわり設計を変えたくなることも多いかなーと思い続けています。
ただ、すでに動いているシステムを変えるのは大変なんですよね。
じゃーどうするの
ソフトウェア自体は動きを止められても、毎日の経済活動を止めることはできない。
だから要は今あるものを動かしつつ、捨てる or やり直すことを前提に処理を書き続けるにはどうするかということを考えるのが良いかなと。
例えば並行でシステムAを動かしながら、同様の振る舞いをするシステムBを動かすなど。
まだまだ自分でも上手く言葉にならないのだけど、いつでも対象システムのマイグレーション(移行)ができるように備えていくのが良いのだと思う。
- この対象システムの裏側の制約を明らかにすること(例: このバッチはなぜこの時間から実行開始しているか、また後続システムではこの処理がいつまでに終わることを期待しているか)
- ビジネスロジックへの(少なくとも)ユニットテストの付加
- ここで行っている処理は短期、中期、長期で使うものなのか。(大体の場合生存期間がビジネスロジックは捨てられビリティをあげる必要あり。なぜならここの施策は短期間で変わるから)
まとめにならないまとめ
なーんてことを近頃考えながらお仕事をすることが多いです。
変更にコストがかかるような状態は本当にしんどく、保守する側の人は疲弊してしまうことが多いんですよね。ビジネスロジックも短期的に必要なものとか、経営方針で変わるものとか、長期で変わらないものとか本来分類できるはずなんですよね。捨てていいフラグとかをビジネスロジックに書いておくとかがあってもいいのかもなーと思ってます。
そのためには、やはり対象システムのやってることの明確化(ドキュメント化を含む)と最低限のユニットテストでもないとそもそもやり直すのも大変になりがちだよなーと思ってます。
最後に
今回の記事はプロトタイプみたいなものなのでどこかでまたupdateをかけたいなと思ってます。
Gradle+KotlinでのJavaのtarget versionの指定のしかたをまとめた
software | version |
---|---|
gradle | 7.2 |
Kotlin | 1.5.30 |
Gradle+ Kotlinの環境でライブラリを書いていたらいつの間にか以下のようなwarningが出るようになってしまいました。
% ./gradlew test > Task :compileKotlin 'compileJava' task (current target is 11) and 'compileKotlin' task (current target is 1.8) jvm target compatibility should be set to the same Java version. > Task :compileTestKotlin 'compileTestJava' task (current target is 11) and 'compileTestKotlin' task (current target is 1.8) jvm target compatibility should be set to the same Java version.
TL;DR
Gradleに以下の設定を入れる。以下はJava8の場合で KotlinDSLを使う場合の例
java { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } // こちらの書き方でもOK // java { // toolchain.languageVersion.set(JavaLanguageVersion.of(8)) // } val compileKotlin: KotlinCompile by tasks compileKotlin.kotlinOptions.jvmTarget = "1.8" // javaの方とversionをあわせる
ググってみた
どうもJavaのtarget versionとKotlinでのjvmTargetの値を両方指定しないといけないらしい。
toolchainの話が出てきたので調べてみたところどうもGradle 6.7から追加された概念らしい(後でもうちょい調べてみよう)
Gradle 6.7 で追加された Toolchain サポート - A Memorandum
Gradleはjava_homeで指定されているバージョンを使おうとするので私はadoptopenjdk11を使っていることもありtarget versionの互換性が〜〜〜というエラーが出るようになった様子。
というわけでこういう書き方をするようにbuild.gradle.ktsを書き直したところビルド時にwarningが出なくなりました。
java { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } // こちらの書き方でもOK // java { // toolchain.languageVersion.set(JavaLanguageVersion.of(8)) // } val compileKotlin: KotlinCompile by tasks compileKotlin.kotlinOptions.jvmTarget = "1.8" // javaの方とversionをあわせる
余談
ちなみに 私はm1 macを使っているせいか toolchain.languageVersion.set(JavaLanguageVersion.of(8))
と書くと
adoptOpenJDKから aarch64版のopenjdk8をダウンロードしてくれようとするのですが、adoptopendjdkでは提供していないため
ビルドしようとするとエラーになってしまうので toolchainを使っていません
gh-extensionsを書いてみた
小ネタです。
ghコマンドが2.0.0になりました
で、mattnさんのこちらのTweetを見て一個ネタを思いついたので早速素振りがてら作ってみました。 何番煎じよと言わないでねw
mobile.twitter.comGitHub の gh コマンドが新しくなり gh-xxx でサブコマンドを取れる様になったので、gh ost でお化けがでるコマンドを作った。https://t.co/amhIewCIE0 pic.twitter.com/59UeY7vJKL
— mattn (@mattn_jp) August 25, 2021
作ったもの
いつでもきゅうり(Gherkin)がみられるコマンドです。
Please enjoy!
Gradleで条件によってdependencyを変える
こんにちは, 僕です。
近頃 Apache Beam にたまにパッチを送るのを趣味で行っているのですが、そこで学んだtipsを紹介します。 今回のテーマはGradleを使っていて条件によってdependencyを変えたい的な要件です。
ちなみにGradleのバージョンは6以降が対象です。
TL;DR
条件によってGradleのdependencyを切り替える。
Gradleだとできそうだなーと思って調べたら結構簡単に見つかりました。
こんな感じでgradleの実行時引数をとって分岐することができるとのこと。
$ gradle -Pgson dependencies --configuration implementation
これを利用すると呼び出しもとのgradleファイル内で変数を参照することも可能でした。 以下のような感じです。
// aaa.gradle spark_scala_version = '2.12'
// bbb.gradle // aaa.gradleから呼ばれる dependencies { // ... if(project.property("spark_scala_version").equals("2.11")){ runtimeOnly library.java.jackson_module_scala_2_11 } else { runtimeOnly library.java.jackson_module_scala_2_12 } // ...
こんな感じで、Javaのバージョンによって参照するライブラリのバージョン分けることも可能なようです。 先人に感謝
Kotlinで書いたアプリのMaven Central Repository への公開手順(Gradle KotlinDSL 版)
- | version |
---|---|
Date | 2021.02.13 |
OpenJDK | OpenJDK Runtime Environment Zulu11.43+1017-CA (build 11.0.9.1+1-LTS) |
kotlin | 1.4.30 |
gradle | 6.8.2 |
Kotlinで書いたアプリのMaven Central Repository への公開手順(Gradle(KotlinDSL)版)
TL;DR
- bintrayに公開していたものを移行するのは割と簡単
- 僕が使っているbuild.gradle.ktsを共有
流れ
こちらのブログが素晴らしく良くまとまっているので参照すると良いと思います。
Tips
いくつか捕捉しておくと良さそうなことを書いておきます。
windowsを使っている方向け
windowsで表題の件をやりたい場合はこちらでgpg keyを作成すると良いと思います。 https://www.gpg4win.org/
gnupgを macportsで入れる
sudo port install gnupg2 # XCodeが必要
RSA keys may be between 1024 and 4096 bits long
ここは (3072) [デフォルト]
になったみたいです。
すでにbintrayに公開済みのjarをmavencentralに移行
JVM言語界隈に激震が走ったこの件について。 bintrayにpublishしているものをmaven centralに移行したい方は以下の感じになります
build.gradle.ktsの書き換えは以下のような感じになります。
抜粋すると
plugins { ... signing // signingを追加. bintrayではこれが必要なかった } ... // repositories { // maven { // name = "bintray" // val bintrayUsername = "masahitojp" // val bintrayRepoName = "maven" // val bintrayPackageName = "com.github.masahitojp.bqdatamapper4k" // setUrl("https://api.bintray.com/content/$bintrayUsername/$bintrayRepoName/$bintrayPackageName/${project.version};publish=0;override=1") // credentials { // username = project.findProperty("bintray_user") as String? // password = project.findProperty("bintray_api_key") as String? // } // } repositories { maven { name = "MavenCentral" val releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2" val snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots" url = uri(if (version.toString().endsWith("SNAPSHOT")) snapshotsRepoUrl else releasesRepoUrl) credentials { username = project.findProperty("sonatypeUsername")?.toString() ?: "" password = project.findProperty("sonatypePassword")?.toString() ?: "" } } } // PGP署名(Mavenセントラルリポジトリに公開するのに必要な署名形式)の追加 signing { sign(publishing.publications["maven"]) }
私がよく使っているbuild.gradle.ktsGradle(KotlinDSL)
plugins { val kotlinVersion = "1.4.30" kotlin("jvm") version kotlinVersion id("org.jetbrains.dokka") version "1.4.20" // Docにはdokkaを使う(ここは自分の好きなのに入れ替えてよし) `maven-publish` signing } group = 'Your Group Id' version = 'X.X.X' val artifactID = "プロジェクト名" repositories { mavenCentral() jcenter() // dokka dependency } dependencies { // Use the Kotlin JDK 8 standard library. implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") // 必要ならライブラリがあれば追加 // Use the Kotlin test library. testImplementation("org.jetbrains.kotlin:kotlin-test") // Use the Kotlin JUnit integration. testImplementation("org.jetbrains.kotlin:kotlin-test-junit") } // Configure existing Dokka task to output HTML to typical Javadoc directory tasks.dokkaHtml.configure { outputDirectory.set(buildDir.resolve("javadoc")) } // Create dokka Jar task from dokka task output val dokkaJar by tasks.creating(Jar::class) { group = JavaBasePlugin.DOCUMENTATION_GROUP description = "Assembles Kotlin docs with Dokka" archiveClassifier.set("javadoc") // dependsOn(dokka) not needed; dependency automatically inferred by from(dokka) from(tasks.dokkaHtml) } // Create sources Jar from main kotlin sources val sourcesJar by tasks.creating(Jar::class) { description = "Assembles sources JAR" archiveClassifier.set("sources") from(sourceSets["main"].allSource) } artifacts { add("archives", sourcesJar) add("archives", dokkaJar) } val jar by tasks.getting(Jar::class) { manifest { attributes( "Implementation-Title" to project.name, "Implementation-Version" to project.version, "Implementation-Vendor" to "masahito.me", "Built-JDK" to "${System.getProperty("java.version")} (${System.getProperty("java.specification.vendor")})", "Built-Gradle" to gradle.gradleVersion ) } } val sonatypeUsername = project.findProperty("sonatypeUsername")?.toString() ?: "" val sonatypePassword = project.findProperty("sonatypePassword")?.toString() ?: "" publishing { publications { create<MavenPublication>("maven") { groupId = project.group.toString() from(components.findByName("kotlin")) artifact(sourcesJar) artifact(dokkaJar) pom { name.set(artifactId) description.set("BigQuery datamapper for Kotlin") url.set("https://github.com/masahitojp/bqdatamapper4k") licenses { license { name.set("Apache License, Version 2.0") url.set("https://opensource.org/licenses/Apache-2.0") } } developers { developer { id.set("Your ID") name.set("Your name") email.set("Your email address") } } scm { connection.set("scm:git:git@github.com:XXXXX.git") developerConnection.set("scm:git:ssh://github.com:XXXXX.git") url.set("https://github.com/XXXXX") } } } } repositories { maven { name = "MavenCentral" val releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2" val snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots" url = uri(if (version.toString().endsWith("SNAPSHOT")) snapshotsRepoUrl else releasesRepoUrl) credentials { username = sonatypeUsername password = sonatypePassword } } } } signing { sign(publishing.publications["maven"]) }
まとめ
- bintrayに公開していたものを移行するのは割と簡単
- 僕が使っているbuild.gradle.ktsを共有
上記をしました。すでにsonatypeにアカウントを作っていればそんなに大変なことはないと思います。 ちょっと古かったりしますがまとめ直してくれていたりする素敵なかたがたくさんいたので僕は1時間くらいで作業を終えることができました。 先人たちに感謝。
karabiner-elementsとM1 MacBook Airでの問題が解決された
- | version |
---|---|
macos | Big Sur 11.6 |
karabiner elements | 13.7.1 |
2021-09-16 update: 無事対解決 タイトルも s/解決されつつある/解決された/g とした
2021-03-04 update: バージョンが上がったが、状況変わらず
https://github.com/pqrs-org/Karabiner-Elements/issues/2517#issuecomment-787000561
こちらによると BigSur 11.3(beta)に上げると解消されたとのこと。macOS側に原因があるということなのかなぁ.
Krabiner Elements v13.1.0をインストールしているとMacを再起動やシステム終了した際に画面がピンクになり、 kernel panicになることが報告されてます。
が、Karabiner ElementsのBeta版を使うことでこの件が修正され、正常に動作した方がいるようです。(M1 mac miniらしい)
I don't see this issue anymore after updating to 13.3.1 with M1 Mac mini and Big sur 11.2. Not sure if this is same for everyone, but anyways thanks a lot for dev team for providing this awesome app!
TL;DR
- Karabiner-Elements beta版を使う(本日時点では 13.3.1)
- ただし効果は人による(少なくともkarabiner-elementsを[システム終了]する前に終了すれば問題が出ない)
Krabiner-Elements Beta の使い方
- Krabiner-Elementsで [preference] を開く
- misc > [Check for beta update] を押下する
- これだけで治る人がいるみたいですが、私の環境ではkarabiner-elementsを終了する -> システム終了 とすることで問題が出なくなりました。(因みにM1 Macbook Air)
参考
先人とKarabiner-Elements開発者に感謝