There are two possibilities I can think of:
- Do you have a file called
numpy.pyin Pythonista? If so, you need to rename it - otherwise
import numpy as npwill import your
numpy.pyand not the standard
- Try restarting Pythonista (swipe up from the bottom of the screen to open the app switcher, then swipe Pythonista upwards to close it, then reopen the app). It is possible that the
numpymodule isn't loaded completely; this can happen if you stop your script while the
import numpystatement is running. By restarting Pythonista, you can bring the Python environment back into a clean state.
- Do you have a file called
Normal Markdown doesn't have any native syntax for underlining -
__underline__produces underline, i. e. bold text. In standard Markdown,
__bold__is equivalent to
_italic_is the same as
Chat applications like Discord, Slack and Mattermost support syntax that is similar to normal Markdown, but isn't completely compatible (they include some custom features that don't exist in Markdown, and don't understand all standard Markdown syntax). Discord's underline feature is an example of that.
@omz I just played around a little and found that
#LyXat the start of a Python script apparently guarantees
fileto recognize it as a LyX document, overriding all of the Python code detection patterns. I'm still on OS X 10.11, but I have a newer
fileversion (5.35) installed through MacPorts, so hopefully its behavior is close to the version that 10.14 has.
I don't quite understand how magic file entries are prioritized and why exactly this works. I'm guessing it's because the LyX pattern looks for a literal string at byte 0, whereas the "smart" Python code detection patterns do a string search over a byte range, so the LyX rule is preferred because it's simpler.
~/.magicis documented in the manpage of my MacPorts version of
file, but not in the OS X default version's manpage. Maybe it's just a version difference, in which case it should work on 10.14. A custom magic file would probably be the best solution, so we don't have to keep looking for new ways to trick
fileevery time they improve their Python patterns.
General question: Does the TestFlight Beta override the installed app or is this separated?
The beta replaces the App Store version. If you already have the App Store version installed and then install the beta through TestFlight, you'll get a warning message saying that you may lose your data - this is generally not the case for Pythonista. (I've been in the Pythonista TestFlight beta since the beginning, and installing a beta has never overwritten my data. But if possible you should make an iTunes backup beforehand, just in case.)
You can also go back to the latest App Store release at any time, by going into your purchases and redownloading Pythonista there. This will replace the beta version, but also leaves your data intact (except perhaps for features that were introduced in the beta).
Being an objc muddler myself, I am wondering why your method and selector do not need to have the trailing underscore/colon.
Objective-C's requirements about where to put colons are only enforced at compile time (they are a part of the language syntax). At runtime it doesn't matter if the colons match up with the method arguments (at that point everything has been translated to regular C function pointer calls), so the runtime never checks the selector names in any way. It's similar to how Python lets you say
setattr(obj, "funny attribute name!", 42), even though you can't use
funny attribute name!as an attribute in your source code.
The underscores in the function name do matter to
create_objc_class, it counts the number of underscores in the name to figure out how many parameters the method has. So even though
controlTouchEvent_sender_eventis not really a correct Objective-C method name, it has two underscores, which matches the number of arguments that the Python function takes (in addition to
_cmd), so the call works in the end.
I didn't even fully grasp how the parameters needed to be defined or named in my function...
The example method (
(IBAction)doSomething:(id)sender forEvent:(UIEvent *)event) would translate to
doSomething:forEvent:as a selector, or
doSomething_event_as a Python function name. Only the word to the left of each colon is part of the selector. The word to the right of each parameter type is the internal parameter name - this only matters if you're implementing the method in Objective-C source code, you can ignore it when translating the method name to
In this case it doesn't matter though what exactly the method name is. You only need to make sure that the underscore/colon count in your function name matches how many arguments the function takes, otherwise
objc_utilwon't call your function with the correct number of arguments.
IIRC block invoke functions take the block itself as an implicit first argument (basically likeNevermind,
self). So you probably need to add an extra
InvokeFuncType's argument list, and add
blkas the first argument in your
blkboth refer to the block.
Also, regardless of whether I like Reddit or not, there are a few things that I think should be considered before moving the community to Reddit:
- @omz You should probably get in touch with the /r/Pythonista moderator and see if you can also become a moderator. (Might be a good idea to mention your Reddit username in a post here, so they can verify that it's actually you contacting them on Reddit.)
- What happens with the existing forum posts? Reddit doesn't support "importing" content, and automatically reposting all forum threads onto Reddit wouldn't work well (everything would be under one account, linear forum threads don't translate well to Reddit's tree-style replies, and this sort of mass posting would probably be considered spam). I suppose the existing threads could be converted to static pages and hosted in place of the forum.
- Could the community be realistically migrated off of Reddit again? Of course there's no "export" feature either, so the content would need to be downloaded some other way (I'm sure there are already tools for that). However there would be no way to redirect old links to the new location.
Also, another thing about Reddit that I forgot to mention in my previous post: after some time, Reddit posts are "archived", which means that they can't be voted or commented on anymore. This would be a problem for threads that are not updated often (for example threads about a specific project that are only updated when a new version is released). I don't know how exactly the archive mechanic works though - if the archive delay is based on the initial post date or the last comment date, or if it can be changed or disabled by moderators in any way.
I don't think a subreddit would be a good replacement for the forum. While Reddit provides the same basic functionality as a forum (you can make posts and reply), I feel like it's mainly a "content sharing" rather than a "discussion" site. On a forum, topics and posts are sorted purely by time; on Reddit the order is also influenced by up- and downvotes. This vote-based ordering works well for finding interesting content related to a topic, but isn't all that useful in a discussion environment (unless there are a lot of posts, which isn't the case for the Pythonista forum).
Reddit also makes it hard to see all recent comments in a subreddit - you can sort posts by new, but this shows the most recently posted posts rather than the most recently commented ones. The same goes for comments on a single post - because of the tree structure, sorting by new shows the most recent top-level comments, rather than comment chains with the most recent replies. Even when logged in, there's no way to see all unread posts/comments like on the forum.
@omz I can totally understand if hosting the forum yourself takes too much time and work. In general I'm not against moving to a different website/service, the points above are about Reddit specifically. (Sadly I don't think there are any good alternatives though...) But tbh whereever the community decides to move, I'll probably go there too, unless it's Facebook or Google Groups.
Well-written C code is easy to compile for different architectures, so the fact that iOS devices use ARM instead of x86 processors isn't a huge problem. CPython supports some ARM platforms natively (mainly Linux), so all of the processor-specific problems have been solved already. iOS is also Unix-based and relatively similar to macOS, so even though CPython doesn't support it natively, the differences aren't huge. There are also projects like https://github.com/pybee/Python-Apple-support, which is basically a set of patches to get CPython working properly on iOS/watchOS/tvOS. (I believe this isn't exactly what Pythonista uses - @omz probably has his own custom version of CPython.)
Interacting between C and Objective-C is also very easy, since Objective-C is more or less an extension of C. This works both ways - you can easily call C code from an Objective-C method, but you can also write regular C functions in Objective-C code, which can use Objective-C features in their implementation, but can also be called from regular C code.
Many of Pythonista's custom modules (like
console, etc.) are implemented using CPython's C API and extension interface, which allows writing Python modules in C. So in principle it's not too difficult to expose iOS Objective-C APIs to Python - you only need to write an extension module in C with some Python-exposed functions that call the appropriate Objective-C APIs. Things get more difficult of course when you also want to provide a nice Pythonic API on the Python side - that requires defining Python classes in C code and converting between Objective-C, C and Python data types where appropriate.
Another way to interact between Python and C is using the
ctypesmodule, which is part of the standard library, and lets you use (almost) any C API from Python at runtime, without having to compile custom C code. This can also be used to interact with Objective-C APIs, because Objective-C's runtime support library provides a pure C interface to most parts of the Objective-C language. Based on this, @omz wrote Pythonista's
objc_utillibrary, which lets you interact with Objective-C APIs and objects from Python. Some of Pythonista's modules (like
editor) are implemented in pure Python using
objc_utilinstead of using CPython's extension API. (There is also a non-Pythonista-specific library called Rubicon, which has similar goals and features as Pythonista's
If I remember correctly, the
enable_faulthandler.pycan't be used as a
pythonista_startup.pydirectly (by default the faulthandler script is meant to be importable, so it doesn't run when loaded). This gist contains the faulthandler script as a working
pythonista_startup.py. (The faulthandler prints a message in the console when it runs, so you can tell when it's working correctly.)