(Not sure why the question is downvoted,1 and you have almost answered it yourself anyway...)
You are nearly there: simply configure push.default to simple or nothing, so that you must specify the push target for this case, and then for your final command, use:
git push origin my-local-branch:some-remote-branch
The way this works is that git push takes, after origin (the name of the remote), a series of refspecs.  A refspec is not very complicated: it's just a pair of names, like master:master, or develop:develop, or develop:foo, optionally with a leading plus sign +, and optionally omitting either the first or second name: :foo or develop.
Refspecs get slightly complicated in that they work differently in git fetch and git push, when you leave out one of the two names.  If you use both names each time, they stay simple: the name on the left is the name on the source repository, and the name on the right is the name on the destination.  For fetch, the source is the remote and the destination is your own repository.  For push, the source is your repository and the destination is the remote.
Leaving out the source name only works with push, and in this case, it means delete.  Hence git push origin :foo means delete foo on remote origin.  (That's not what you want, so avoid that.)
Leaving out the destination name works with both fetch and push but means different things to them.  Let's just ignore fetch here.  With push, it means use the same name on both local and remote.  Since you don't want that here, don't use it here.  (Or, for those cases where you do want it, go ahead and use it.)
The leading + sign, if present, means the same as --force.  (In fact --force just adds the + on everything.)
If you run git push origin, or git push (without even a remote argument), Git looks up push.default to see what to push.  Setting it to nothing means just fail / error-out, so that I have to type in a refspec.  Setting it to simple means push just one branch, the current branch, to the current branch's upstream, but also require that the upstream name match.  Since my-local-branch and some-remote-branch don't match, this will fail for your case of local branch foo is tracking remote-tracking branch origin/develop: the names foo and develop do not match.
Either way, Git will force you to enter a refspec for this push.
With the nothing configuration, Git will force you to enter a refspec for every push.  (I have used this and it works, but it's not terribly convenient.)  With the simple configuration, Git will allow you to push your develop to the upstream develop easily, and will allow you to push your foo to an upstream develop (or an upstream jazzy, or any other name but foo) explicitly, but won't push foo to foo since that's not its defined upstream.  (I have used this and it works better.)
As of Git version 2.0, simple is the default configuration.  So if you have Git version 2.0 or later, you are already good to go.  If not, see if you can upgrade your Git version, but push.default is configurable as far back as Git version 1.6.  (I'm not sure what values it could take on, then.  The current set-of-5 values goes back to 1.7.11 if not earlier, I think.)
For completeness, the other three possible values are: current, upstream, and matching.  The current value means use the current branch's name: git push origin $branch:$branch where $branch is the current branch.  The upstream value means use the current branch's upstream name: git push origin $branch:$merge, where $merge is from git config --get branch.$branch.merge.
The matching value is the hardest to describe, and was the default before Git version 2.0: it means get a list of every branch on the remote, and match up their names and our local branch names, and then do an en-masse push of all of our local branches to the branch of the same name on the remote, wherever the two names match up.  This is not a very safe setting, although as long as you do not use --force, it actually works pretty well in practice, which is why it was usable for so many years.
Side notes: terminology
Git's terminology is kind of a mess.
- A local branch (or just "a branch" or "a branch name"), like - master, is a name in the- refs/heads/name-space.  It points to a commit ID.  When you make a new commit while on that branch, Git reads the commit ID, makes the new commit with that ID as the new commit's parent, and then writes the new commit's ID into the branch-name, so that the branch now points to the new commit (which in turns points to the previous branch-tip, and so on).
 - You can - git checkouta local branch, which puts you on "on the branch", so that- git statussays- On branch masterfor instance.  This sets things up so that new commits advance the branch, as I just noted above.
 
- A remote-tracking branch like - origin/masteris a name in the- refs/remotes/name-space.  After- refs/remotes/we find the name of the remote itself,- origin, then another slash, and finally the name of the branch as seen on that remote (sans- refs/heads/of course).  These names are stored locally, in your own repository: they're not actually remote at all.  They are just automatically updated when your Git contacts the remote, through- git fetchand (to a more limited extent) through- git push.
 - You can - git checkouta remote-tracking branch, but if you do,- git checkoutputs you in "detached HEAD" mode, so that- git statusand- git branchclaim you're not on any branch (or are on "no branch" or similar, sometimes using the "detached HEAD" phrasing).  When this happens you are actually on the (single, special) anonymous branch.  When you get back on a normal branch, any work you did on the anonymous branch will eventually fade away.  (So if you want to keep the work, set up a name, so that it's not anonymous anymore—or use- git checkoutto get back on a regular branch, before you do that work.)
 
- A local branch can track another branch (local or remote).  When local branch B is tracking another branch U, Git calls this the "upstream" of the local branch.  This upstream is composed of two parts: the name of the remote, like - origin, and the name of the branch as seen on the remote, like- master.  To track a local branch as your upstream for branch B, Git just sets the remote to- .instead.
 - Hence local branch B is tracking upstream U if it has these two items configured.  U is itself normally a remote-tracking branch, which is a local entity (one of those - refs/remotes/name-space names).  You must- git fetchor- git pushto get the remote-tracking branch(es) updated, after which- git statusand- git branch -vvwill report local branches that are tracking the remote-tracking branches, as being ahead and/or behind their counterparts.
 - Local branch B can instead track another local branch as its upstream.  In this case, since everything is locally-updated, - git statusand- git branch -vvwill be up-to-date without any- git fetchneeded.
 - A local branch B need not track anything, of course.  The commands - git branch --set-upstream-to upstreamand- git branch --unset-upstreamwill set or unset the upstream of the current branch.  You can also set, change, and examine the two individual parts of the upstream (the- branch.$branch.remoteand the- branch.$branch.mergeparts) using- git config, although using- git branchis usually nicer and more convenient.
 
1Perhaps the downvote is because of the Git 2.0 default push.default.